¿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.

  • Renderiza la respuesta json en Kotlin
  • no se puede llamar al module kotlin desde el module java
  • Error al ejecutar un proyecto de Android (escrito en Kotlin) comstackdo con el complemento Gradle2.0.0-alpha
  • Errores HashMap - containsKey, get
  • Usar puntos en identificadores xml
  • ¿Cómo leer un file de text de resources en Kotlin?
  • En Kotlin, ¿cómo se modifican los contenidos de una list mientras se itera
  • Nombre de image dibujable inaccesible en Kotlin?
  • Error al hacer que Enum sea la key principal en la biblioteca de la database de la sala
  • Cómo usar Spek
  • Proveedor de contenido en Android de Kotlin