val - Kotlin: Aplicar vs Con
val y var kotlin (3)
¿Cuál es la diferencia entre with y apply? Por lo que sé, el siguiente código hace lo mismo:
swingElement.apply {
minWidth = ENABLED_COLUMN_WIDTH
maxWidth = ENABLED_COLUMN_WIDTH
preferredWidth = ENABLED_COLUMN_WIDTH
}
with(swingElement) {
minWidth = ENABLED_COLUMN_WIDTH
maxWidth = ENABLED_COLUMN_WIDTH
preferredWidth = ENABLED_COLUMN_WIDTH
}
¿Hay alguna diferencia y debo usar una sobre la otra? Además, ¿hay algunos casos en que uno funcionaría y el otro no?
La función de
apply
//returns receiver T, T exposed as `this`
fun <T> T.apply(block: T.() -> Unit): T
Descripción
La función de
apply
se invoca en un receptor
T
, que se expondrá como
this
en la expresión lambda aprobada.
El receptor también se convierte en el resultado de
apply
automáticamente.
La función
with
//return arbitrary value R, not an extension function, T exposed as `this`
fun <T, R> with(receiver: T, block: T.() -> R): R
Descripción
La función
with
, a diferencia de todas las demás funciones de ámbito (
let
,
run
,
also
,
apply
),
no se define como una función de extensión
.
En cambio, la función se invoca con un objeto receptor como su primer argumento explícitamente.
Igual que
apply
, el receptor está expuesto como
this
en la lambda aprobada.
El resultado de la lambda, es decir, su última declaración, se convierte en el resultado (
R
) de
with
.
Aquí están las similitudes y diferencias
Similitudes
Con y Aplicar, ambos aceptan un objeto como receptor de cualquier manera que se les pase.
Las diferencias
Con devuelve la última línea en la lambda como resultado de la expresión.
Aplicar devuelve el objeto que se pasó como receptor como resultado de la expresión lambda.
Ejemplos
Con
private val ORIENTATIONS = with(SparseIntArray()) {
append(Surface.ROTATION_0, 90)
append(Surface.ROTATION_90, 0)
append(Surface.ROTATION_180, 270)
append(Surface.ROTATION_270, 180)
}
ORIENTATIONS[0] // doesn''t work
// Here, using with prevents me from accessing the items in the SparseArray because,
// the last line actually returns nothing
Aplicar
private val ORIENTATIONS = SparseIntArray().apply {
append(Surface.ROTATION_0, 90)
append(Surface.ROTATION_90, 0)
append(Surface.ROTATION_180, 270)
append(Surface.ROTATION_270, 180)
}
ORIENTATIONS[0] // Works
// Here, using apply, allows me to access the items in the SparseArray because,
// the SparseArray is returned as the result of the expression
Hay dos diferencias:
-
apply
acepta una instancia como receptor mientras que requiere que una instancia se pase como argumento. En ambos casos, la instancia se convertirá enthis
dentro de un bloque. -
apply
devuelve el receptor ywith
devuelve un resultado de la última expresión dentro de su bloque.
No estoy seguro de que pueda haber algunas reglas estrictas sobre qué función elegir.
Por lo general, utiliza
apply
cuando necesita hacer algo con un objeto y devolverlo.
Y cuando necesite realizar algunas operaciones en un objeto y devolver algún otro objeto, puede usarlo
with
o
run
.
Prefiero
run
porque es más legible en mi opinión, pero es cuestión de gustos.