Aprendizaje de Kotlin: las funciones estándar permiten, con, ejecutan, aplican, también en Kotlin

Funciones estándar de Kotlin:

Función estándar let

fun main() {
    
    
    val student = Student("lucky", 19);
    study(student)
}

fun study(student: Student?) {
    
    
    study?.doHomework()
    study?.readBooks()
}

En el aprendizaje de Kotlin - tipo de sistema anulable , si el parámetro de entrada es anulable, debe agregarse cada vez que se llama a la función del objeto en la función ?., y la escritura del código es demasiado engorrosa. En este momento, puede combinar ?.operadores y letfunciones para optimizar el código, como se muestra a continuación:

fun main() {
    
    
    val student = Student("lucky", 19);
    study(student)
}

fun study(student: Student?) {
    
    
    student?.let {
    
     s ->
        s.doHomework()
        s.readBooks()
    }
}

?.El operador significa no hacer nada cuando el objeto está vacío y llamar leta la función cuando el objeto no está vacío. Cuando estaba haciendo la optimización de la expresión lamda antes ( aprendizaje de Kotlin - colección ): cuando solo hay un parámetro en la lista de parámetros de la expresión Lambda, no es necesario declarar el nombre del parámetro, pero se puede usar la palabra clave it en su lugar, por lo que el código anterior se puede optimizar hacia abajo:

fun main() {
    
    
    val student = Student("lucky", 19);
    study(student)
}

fun study(student: Student?) {
    
    
    student?.let {
    
    
        it.doHomework()
        it.readBooks()
    }
}

letAdemás de ayudarnos a simplificar el juicio no nulo, los subprocesos múltiples también pueden controlar el juicio nulo de las variables globales.

var student: Student? = null

fun study() {
    
    
    if (student !=null){
    
    
        student.doHomework()
        student.readBooks()
    }
}

El código anterior compilará e informará un error, porque el valor de la variable global puede ser modificado por otros subprocesos en cualquier momento Incluso si se realiza el juicio nulo, aún no puede garantizar que la variable ifen la declaración studentno tenga riesgo de nulo puntero. Utilice letla función para modificar:

var student: Student? = null

fun study() {
    
    
    student?.let {
    
    
		it.doHomework()
		it.readBooks()
    }        
}

Después de que desaparezca el error y se juzgue que la variable no está vacía, ejecute la declaración en let. let puede asegurarse de que la variable no esté vacía studentdurante la ejecución de la declaración lambda .student

Resumen: letPuede ayudarnos a simplificar el juicio no nulo, y también puede controlar el juicio nulo de variables globales en subprocesos múltiples.

función estándar con

fun main() {
    
    
    val fruits = listOf("apple", "banana", "pear")
    println(fruitPrint(fruits))
}

Hay una lista de frutas arriba, y el requisito es unirlas en un formato fijo. El método de implementación habitual es el siguiente:

fun fruitPrint(fruits: List<String>): String {
    
    
    val fruitPrint = StringBuilder();
    fruitPrint.append("My favorite fruits are : \n")
    
    for (f in fruits) {
    
    
        fruitPrint.append(f).append("\n")
    }
    
    fruitPrint.append("----- end -----")
    return fruitPrint.toString()
}

//打印结果
My favorite fruits are : 
apple
banana
pear
----- end -----

El objeto se llama varias veces seguidas donde se empalma la cadena StringBuilder. Para este escenario, podemos usar withfunciones para simplificar el código.

fun fruitPrint(fruits: List<String>): String {
    
    
   return with(StringBuilder()) {
    
    
        append("My favorite fruits are : \n")
        for (f in fruits) {
    
    
            append(f).append("\n")
        }
        append("----- end -----")
        toString()
    }
}

Si withse pasa un objeto como primer parámetro de la función StringBuilder, el contexto de toda la expresión de Lambda será este StringBuilderobjeto. Entonces podemos llamar directamente append()y toString()método en la expresión Lambda. La última línea de código de la expresión lambda se withdevuelve como valor de retorno de la función.

Resumen: cuando se requieren operaciones frecuentes en el mismo objeto, withse pueden usar funciones para simplificar el código.

ejecución de función estándar

runEl uso de funciones withes muy similar a las funciones, pero runlas funciones generalmente no se llaman directamente, sino que se llaman sobre la base de un objeto. Y withhay dos parámetros de entrada, runsolo un parámetro de entrada de expresión Lambda.

Del mismo modo, la última línea de código en la expresión lambda de withy se devuelve como valor de retorno.run

El ejemplo anterior se puede runreescribir como una función:

fun fruitPrint(fruits: List<String>): String {
    
    
   return StringBuilder().run {
    
    
        append("My favorite fruits are : \n")
        for (f in fruits) {
    
    
            append(f).append("\n")
        }
        append("----- end -----")
        toString()
    }
}

aplicación de la función estándar

applyLas funciones runson similares a las funciones, deben invocarse en un objeto y solo recibir un parámetro Lambda, y el contexto del objeto invocador también se proporcionará en la expresión Lambda, pero la función de aplicación no puede especificar el valor de retorno, sino que lo hará automáticamente. devolver el objeto de llamada en sí.

fun fruitPrint(fruits: List<String>): String {
    
    
     val sb = StringBuilder().apply {
    
    
        append("My favorite fruits are : \n")
        for (f in fruits) {
    
    
            append(f).append("\n")
        }
        append("----- end -----")       
    }
    return sb.toString()
}

Dado que applyla función no puede especificar el valor de retorno, solo puede devolver el objeto de llamada en sí, por lo que no se puede devolver directamente.Nuestro valor de retorno declara el tipo String, por lo que debe convertirse.

Veamos el uso en Android:

val intent = Intent(this,MainActivity::class.java).apply {
    
    
	putExtra("data1","data1")
	putExtra("data2",2)
	putExtra("data3",true)
}
startActivity(intent)

Al iniciar MainActivity, puede ir a Intentlos parámetros contenidos en la configuración.

función estándar también

El uso de also es similar al de apply, vea un ejemplo:

fun studentInfoCheck(s: Student) {
    
    
    s.also {
    
     it.name = "Lucky" }
    println(s.name)
}

Usado internamente itpara referirse al contexto, se puede realizar una serie de operaciones sobre el objeto. El valor de retorno applysolo puede devolver el objeto de llamada en sí.

Diferencias en funciones estándar

¿Estás confundido por aprender aquí? Comparemos las diferencias de las siguientes funciones y se verá más claro.

función estándar contexto interno valor de retorno
dejar él La última línea de código en el bloque let
con esto (se puede omitir) La última línea de código en el bloque let
correr esto (se puede omitir) La última línea de código en el bloque let
aplicar esto (se puede omitir) llamar al objeto mismo
también él llamar al objeto mismo

La diferencia entre con y correr

De la tabla anterior, el contexto interno y el valor de retorno withde y runson los mismos, entonces, ¿cuál es la diferencia entre los dos?

  • withHay dos parámetros de entrada, runsolo un parámetro de entrada de expresión Lambda;
  • Los métodos de evaluación de la seguridad aérea son diferentes;

Para el segundo punto, echemos un vistazo al caso:

fun printStudentInfo() {
    
    
	val s: Student? = null
	with(s) {
    
    
	    this?.name = "Tom"
	    this?.age = 4
	}
	print(s)
}

Lo anterior es para usar withel juicio vacío. Al usarlo, debe juzgar el no vacío nuevamente cada vez, cámbielo runpara probar

fun printStudentInfo() {
    
    
	val s: Student? = null
    s?.run {
    
    
        name = "Tom"
        age = 4
    }
	print(s)
}

En primer lugar, runla llamada a la función omite thisla referencia, y la verificación de seguridad vacía se lleva a cabo en la capa externa, y solo cuando no está vacía puede ingresar al bloque de funciones para operar Student. En comparación with, runlas funciones son más simples y las comprobaciones de seguridad nulas son menos withfrecuentes.

Artículo de referencia
Diferencias entre let, run, with, apply y también en Kotlin

Supongo que te gusta

Origin blog.csdn.net/kongqwesd12/article/details/131293825
Recomendado
Clasificación