descargar - kotlin vs scala
Diferencia entre con y correr en Kotlin (2)
Do with
y run
tienen la misma funcionalidad con solo una sintaxis diferente, o hay alguna diferencia importante entre with
y run
?
¿Cuál es la forma correcta?
adapter.run {
notifyDataSetChanged()
if (activityDetails.isEmpty())
emptyText.visibility = View.VISIBLE
else
emptyText.visibility = View.GONE
}
with(adapter){
notifyDataSetChanged()
if (activityDetails.isEmpty())
emptyText.visibility = View.VISIBLE
else
emptyText.visibility = View.GONE
}
En el caso normal, son bastante similares, pero para una variable que puede T.run()
, es mejor usar T.run()
Por ejemplo, si webview.settings
es anulable, a continuación se muestran las distintas
with(webview.settings) {
this?.javaScriptEnabled = true
this?.databaseEnabled = true
}
// similarly
webview.settings?.run {
javaScriptEnabled = true
databaseEnabled = true
}
Solo tienen una diferencia sintáctica, run
es una función de extensión, mientras que with
no lo es. Aquí están las definiciones (en kotlin-sdlib:1.0.3
):
public inline fun <T, R> T.run(block: T.() -> R): R = block() // equivalent to this.block()
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
Dado que run
es una función de extensión, tiene un argumento implícito más de tipo T
, por lo que los tipos de argumento son los mismos. Los cuerpos de las funciones también son efectivamente los mismos.
Su rendimiento también debe ser equivalente, ya que ambas son funciones en inline
: el código de bytes resultante solo debe contener el cuerpo del block
línea.
Las diferencias en el uso de las funciones son todas causadas por el hecho de que la run
es una extensión.
En primer lugar, run
es adecuado para el encadenamiento de llamadas:
foo.run { bar }.run { baz }
Segundo, y más importante, si un tipo de variable declarado tiene una función de run
con la misma firma, se llamará en lugar de la extensión. Y run
puede ser sombreado por otra extensión. Así es como se resuelven las extensiones . Ejemplo:
class MyClass {
fun <R> run(blockIgnored: MyClass.() -> R): Nothing = throw RuntimeException()
}
"abcdefg".run { println("x") } // prints "x"
MyClass().run { println("x") } // throws RuntimeException
(MyClass() as Any).run { println("x") } // prints "x"