¿Cuál es el propósito de Lambda's con Receiver?

¿Cuál es el propósito de Lambda's con Receiver en Kotlin, mientras tenemos funciones de extensión?

Dos funciones a continuación hacen las mismas cosas, sin embargo, la primera es más legible y breve:

fun main(args: Array<String>) { println("123".represents(123)) println(123.represents("123")) } fun String.represents(another: Int) = toIntOrNull() == another val represents: Int.(String) -> Boolean = {this == it.toIntOrNull()} 

Las lambdas con receptores son básicamente las mismas que las funciones de extensión, solo pueden almacenarse en properties y transferirse a las funciones. Esta pregunta es esencialmente la misma que "¿Cuál es el propósito de lambdas cuando tenemos funciones?". La respuesta es muy similar: le permite crear rápidamente funciones de extensión anónimas en cualquier parte de su código.

Hay muchos buenos casos de uso para esto (ver DSL especialmente), pero aquí daré un ejemplo simple.

Por ejemplo, digamos que tienes una function como esta:

 fun buildString(actions: StringBuilder.() -> Unit): String { val builder = StringBuilder() builder.acitons() return builder.build() } 

Llamar a esta function se ve así:

 val str = buildString { append("Hello") append(" ") append("world") } 

Hay un par de cosas interesantes que esto permite:

  • Dentro de la lambda pasas a buildString estás en un nuevo ámbito, tienes nuevos methods y properties disponibles para usar. En este caso específico, puede usar methods en el tipo StringBuilder sin tener que llamarlos en ninguna instancia.
  • La instancia real de StringBuilder estas llamadas a funciones no es gestionada por usted; es hasta la implementación interna de la function para crear una y llamar a su function de extensión.
  • Del punto anterior se desprende que esta function podría hacer mucho más que simplemente llamar a la function que le pasó una vez: podría llamarla varias veces, en varias instancias de StringBuilder , almacenarla para un uso posterior, etc.
  • Emitir no seleccionado al lanzar un object de tipo Cualquiera? en una lambda en kotlin
  • Kotlin filter lambda array usando el índice de iteración
  • Enlace de datos: el campo Observable con valor lambda no comstack
  • Cuando los parameters lambda deben ser noinline en Kotlin?
  • ¿Por qué la variable no se puede inicializar correctamente en la function en línea como en Java?
  • Kotlin: ¿Cómo puedo invocar un campo lambda que tiene un tipo genérico de su class?
  • Cómo escribir el generador HTML correcto en Kotlin
  • Kotlin: ¿Para qué se llaman los arguments lambda?
  • Pasar funciones a funciones en Kotlin
  • ¿Por qué Kotlin no puede inferir el siguiente argumento lambda (después de la conversión de Java -> Kotlin)?
  • cómo descartar DialogFragment de lambda especificado en el llamador Kotlin