Funciones de Alcance
Explicación del concepto, usos y tipos.
DEFINICIÓN
Las funciones de alcance sirven para hacer nuestro código más legible. Cuando tenemos varias lineas de código que operan con un objeto, estas se pueden cambiar por una función de alcance que aclara el código.
Por tanto, las funciones de alcance son aquellas cuyo único propósito es ejecutar un bloque de código dentro del contexto de un objeto.
La librería estandar cuenta actualmente con las siguientes funciones de alcance:
also
let
apply
run
with
DIFERENCIAS
Hay dos elementos que las diferencian:
Como accedemos al objeto:
Para las funciones
let
yalso
utilizamos la palabra reservada it.Para
run
,with
yapply
utilizamos this.
Que valor retorna
apply
yalso
devuelven el objeto como tal.let
,run
ywith
devuelven el valor de retorno del lambda, es decir, retorna el valor de nuestra última sentencia ejecutada.
TIPOS
also
also
, tiene un buen uso cuando realizamos algunas acciones que no están estrictamente relacionadas con el objeto en sí, pero que lo utilizan como argumento.
Se lee como: y también realiza lo siguiente.
data class Zapato(
var size: Int = 38,
var color: String = "Negro",
var stock: Int = 10
)
// Sin utilizar el with
fun main() {
val zapatoNuevo = Zapato()
val datosZapato = zapatoNuevo.apply {
size = 42
color = "Rojo"
stock = 25
}.toString()
print(datosZapato)
}
// Utilizando el with
fun main() {
val zapatoNuevo = Zapato().apply {
size = 42
color = "Rojo"
stock = 25
}.also {
print(it)
}
}
Como apply
devuelve la nueva instancia de Zapato()
almacenada en zapatoNuevo
, podemos utilizar also
para imprimirlo.
let
let
, se suele utilizar en dos situaciones distintas:
Cuando queremos ejecutar un bloque de código solo con valores no nulos.
Para invocar una o más funciones con resultados en cadena.
La función let
siempre va acompañada de una lambda.
fun main() {
val invoice = Invoice(
"Fabricia",
listOf(
InvoiceLine(5.0),
InvoiceLine(4.0),
InvoiceLine(6.0)
)
)
val invoiceDetail = invoice.let {
val total = it.lines.sumOf { line -> line.unitCost }
"La factura de ${it.customer} tiene un total de $total"
}
println(invoiceDetail)
}
apply
apply
, es común utilizarlo para la inicialización de objetos.
Se lee como: aplicar las siguientes asignaciones al objeto.
// Esta es la clase de la que queremos generar una instancia
data class Zapato(
var size: Int = 38,
var color: String = "Negro",
var stock: Int = 10
)
// Ahora inicializamos el objeto con apply
fun main() {
val zapatoNuevo = Zapato().apply {
size = 42
color = "Rojo"
stock = 25
}
}
run
run
se suele utilizar cuando inicializamos una variable seguido de una interacción con la misma.
Tiene la particularidad de que no siempre es necesario utilizar el this
para referenciar al objeto dentro del scope:
fun main() {
val resultado = "Ejemplo".run {
println("El String \"$this\" tiene $length caracteres")
length
}
}
with
with
, a diferencia de las demás funciones, pasa al objeto como parámetro en vez de ser el objeto quién llame a la función. Se suele utilizar en contextos donde no necesitamos obtener un resultado en sí mismo, sino que queremos aplicar una operación con/sobre el objeto.
Se lee como: con este objeto, hacemos lo siguiente.
val numbers = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers) {
"The first element is ${first()}," +
" the last element is ${last()}"
}
print(firstAndLast)
Last updated