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

  • ¿El comstackdor de Kotlin siempre conserva los nombres de los parameters en bytecode?
  • Para una function de Kotlin utilizada como expresión, ¿hay una forma concisa de operar y devolver un valor?
  • Gson no puede analizar datos de formatting de cadena json en Kotlin
  • Cómo express `Class <? extiende Any> `
  • Guice MapBinder
  • ¿Cómo declarar un iterador sin inicializarlo? (Kotlin)
  • Location.distanceTo devuelve valor en metros pero necesito pies
  • Kotlin: hacer visible una function interna para testings unitarias
  • Eliminar ruptura en Kotlin cuando expresión
  • Kotlin: No se puede devolver un tipo derivado
  • Función de extensión Android Studio 3.0 kotlin 'Referencia no resuelta'