Las funciones de alcance ("funciones de ámbito") en Kotlin son funciones estándar (let, also, run, apply, with) que permiten gestionar el contexto de ejecución de un bloque de código para un objeto. Se diferencian en:
it o a través de this.| Función | this/it | Devuelve | ¿Para qué? |
|---|---|---|---|
| let | it | resultado | cadena de operaciones, trabajo con nullable, map |
| also | it | objeto | efectos secundarios, registro, depuración |
| run | this | resultado | cálculos, inicialización con retorno |
| apply | this | objeto | configuración de objeto, constructores |
| with | this | resultado | trabajo con API externas, objeto "desde afuera" |
Ejemplos:
let: conveniente si el objeto es nullable:val str: String? = "Texto" str?.let { println(it.length) }
apply: configuración de objeto:val paint = Paint().apply { color = Color.RED strokeWidth = 2f }
run: ejecución sobre el objeto, devuelve el resultado:val length = "abcde".run { length }
with: para trabajar con un objeto externo:val sb = StringBuilder() with(sb) { append("Hola, ") append("mundo!") toString() }
also: para efectos secundarios (por ejemplo, registros):val list = mutableListOf(1, 2, 3) list.also { println("Antes: $it") }.add(4)
it, no es muy conveniente cambiar las propiedades del objeto.this / it), útil para constructores.with es una función normal, no una extensión.¿Cuál es la diferencia entre let y also?
Respuesta:
it dentro del bloque,let devuelve el resultado de la lambda, a menudo se usa para cadenas de transformación,also devuelve el objeto original, se usa para efectos secundarios (registro, depuración), para no interferir en la cadena de transformación.Ejemplo:
val result = listOf(1).also { println(it) }.map { it * 2 } // resultado — List<Int>
Historia
Un principiante utilizó let para configurar un objeto, pensando que podía cambiar su estado "en la cadena". Como resultado, al finalizar el bloque de configuración, obtenía no un objeto, sino el resultado de la lambda (por ejemplo, nada), lo que rompía la cadena de construcción de DSL.
Historia
Al escribir código para trabajar con objetos nullable, usaron run en lugar de let, sin notar la diferencia en el valor devuelto. Al final, el resultado de la expresión difería del esperado, apareciendo null donde no debería haber — la lógica de la aplicación se rompía.
Historia
En un gran constructor, usaron accidentalmente with para objetos internos, esperando el patrón de extensión. Dado que with no es una función de extensión, la cadena de varios bloques with no funcionaba correctamente, las llamadas internas se confundían y salían del objeto actual. Tuve que reescribir completamente la jerarquía de creación de objetos.