Funciones estándar (Scope Functions) III: apply y also
Tercera entrega sobre las funciones estándar (revisar las entradas Funciones estándar I: let y Funciones estándar II: with y run), que se centra en las funciones apply() y also().
apply
En esta función el objeto está disponible como un receptor (this) y su valor de retorno es el objeto.Es común usar apply para bloques de código que no devuelven un valor y operan con los miembros del objeto receptor, habitualmente para inicializar o configurar el objeto. Así, cuando se utiliza apply se puede interpretar como "aplicar las siguientes asignaciones al objeto", por ejemplo:
data class Persona(var nombre: String, var edad: Int = 0, var ciudad: String = "") fun main() { val persona1 = Persona("Juan").apply { edad = 32 ciudad = "Valencia" } }
Otra manera de escribir lo mismo:
data class Persona(var nombre: String, var edad: Int, var ciudad: String) { constructor() : this("", 0, "") } fun main() { val persona1 = Persona() val persona1Data = persona1.apply { nombre = "Juan" // this.nombre o persona1.nombre edad = 32 ciudad = "Valencia" }.toString() }
Otro ejemplo:
enum class Color { ROJO, AZUL } data class PaletaColores( var color1: Color = Color.AZUL, var color2: String = "default" ) fun main() { val paleta = PaletaColores().apply { color1 = Color.ROJO color2 = "Blanco" } println(paleta) }
Teniendo el receptor como valor de retorno, podemos incluir apply en llamadas encadenadas para un procesamiento más complejo.
fun main() { val numeroTelefono = "8899665544" numeroTelefono.apply { println(contains("8")) // true println(length) // 10 } }
also
En la función also() el objeto está disponible como un argumento (it) y el valor de retorno es el objeto en sí. Cuando vemos la función also() en el código, podemos interpretarla como "y también hacer lo siguiente...".fun main() { val numeros = mutableListOf("uno", "dos", "tres") numeros .also { println("Antes: $it") } .add("cuatro") println("Después: $numeros") }
En ocasiones es útil para acciones que no alteran el objeto, como registrar o imprimir información de depuración.
data class Persona(var nombre: String, var edad: Int, var ciudad: String) { constructor() : this("", 0, "") } fun personaLog(p: Persona) { println("Nuevo contacto creado: ${p.nombre}.") } fun main() { val persona1 = Persona("Juan", 32, "Valencia") .also { personaLog(it) } }
Como hemos visto en esta serie dedicada a las funciones estándar, a la hora de elegir una función estándar puede resultar confuso decidirnos por una u otra. A modo de resumen, en la siguiente tabla se ven rápidamente las diferencias entre ellas:
Función | Referencia al Objeto | Valor de Retorno |
---|---|---|
let | it | lambda |
run | this | lambda |
with* | this | lambda |
apply | this | objeto |
also | it | objeto |
Comentarios
Publicar un comentario