¿Qué significa una firma de function de Kotlin con T. ()?

Esta es una function estándar de Kotlin (hasta donde yo sé)

inline fun<T> with(t: T, body: T.() -> Unit) { t.body() } 

Pero, ¿podría alguien escribir en inglés simple qué significa exactamente la firma? Es una function genérica para T, con el primer argumento "t" de tipo T y el segundo, "cuerpo" de tipo de function, aceptando una function de ???? y no devuelve nada (Unidad)

Veo esta notación Algo. () -> Algo se usa con bastante frecuencia, es decir, para Anko:

 inline fun Activity.coordinatorLayout(init: CoordinatorLayout.() -> Unit) = ankoView({ CoordinatorLayout(it) },init) 

pero no creo que haya sido explicado en ningún lado. () significa …

T.() -> Unit es un tipo de function de extensión con receptor.

Además de las funciones ordinarias, Kotlin admite funciones de extensión. Tal function difiere de una ordinaria en que tiene una especificación de tipo de receptor. Aquí hay una parte genérica de T.

La palabra key this dentro de una function de extensión corresponde al object receptor (el que se pasa antes del punto), por lo que puede llamar a sus methods directamente (aún es posible hacer reference a this desde ámbitos primarios con calificadores ).

La function with es una estándar, sí. Es código actual:

 /** * Calls the specified function [f] with the given [receiver] as its receiver and returns its result. */ public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f() 

Entonces, es una function genérica para T y R , con el primer argumento "receptor" de tipo T y el segundo, f del tipo de function de extensión, que extiende T , devolviendo el tipo R que a su vez es devuelto por with .

Por ejemplo, puede usarlo así:

 val threadInfoString = with (Thread.currentThread()) { // isDaemon() & getPriority() are called with new property syntax for getters & setters "${getName()}[isDaemon=$isDaemon,priority=$priority]" } 

Ver la documentation para funciones de extensión aquí:
kotlinlang.org/docs/reference/lambdas.html#extension-function-expressions
kotlinlang.org/docs/reference/extensions.html


Adicional:

Entonces, ¿la única f válida sería cualquier function de 0 arguments definida para T?

Realmente no. En Kotlin , los types de funciones y los types de funciones de extensión están unificados , por lo que se pueden usar indistintamente. Por ejemplo, podemos pasar String :: length donde se espera una function (String) -> Int .

 // map() expects `(String) -> Int` // argument has type `String.() -> Int` strings.map(String::length) 

Los types como Thread.() -> String & (Thread) -> String son los mismos desde el lado del background: el receptor, de hecho, es el primer argumento.

Por lo tanto, cualquiera de las siguientes funciones es adecuada para Thread.() -> String argument:

 fun main(args: Array<String>) { val f1 = fun Thread.(): String = name val f2 = fun Thread.() = name val f3: Thread.() -> String = { name } val f4: (Thread) -> String = { it.name } val f5 = { t: Thread -> t.name } val f6: (Thread) -> String = Thread::getNameZ val f7: Thread.() -> String = Thread::getNameZ val f8 = Thread::getNameZ } fun Thread.getNameZ() = name 

O simplemente puede usar la function literal ( {} ) como en el ejemplo con threadInfoString , pero solo funciona cuando el tipo de receptor se puede inferir del context.

  • Asignar un solo elemento a un atributo de valor IntArray en las annotations de Kotlin
  • Kotlin y la confusión de generics
  • Moshi en Android Kotlin - ENUM como key MutableMap que se convierte en String cuando se desexcita
  • Extensiones de Kotlin para Android y menu
  • Complemento con id `kotlin` no encontrado
  • ¿Cómo puedo reutilizar / componer parte de una consulta JOOQ en un método de repository?
  • ¿Puede kotlin definir el método dynamic cuando la class init?
  • Una forma más simple o más funcional de encadenar objects en Kotlin
  • Métodos sobrecargados que reciben funciones de order superior en Kotlin
  • NoSuchMethodError utilizando Kotlin con el nuevo data binding de Android
  • Buscando con RxJava no funciona