带T.()的Kotlin函数签名是什么意思? [英] What does a Kotlin function signature with T.() mean?
问题描述
这是标准的Kotlin函数(据我所知)
This is a standard Kotlin function (as far as I know)
inline fun<T> with(t: T, body: T.() -> Unit) { t.body() }
但是任何人都可以用简单的英语写出签名的确切含义吗?这是T的泛型函数,第一个参数为"t" 类型T的第二个,函数类型的第二个主体",接受????的功能并且不返回任何内容(单位)
But could anyone write in simple English what does exactly the signature mean? It's a generic function for T, with first argument "t" of type T and second, "body" of function type, accepting a function of ???? and returning nothing (Unit)
我看到这种表示法Something.()-> Something的使用非常频繁,例如Anko:
I see this notation Something.() -> Something is used pretty frequently, i.e. for Anko:
inline fun Activity.coordinatorLayout(init: CoordinatorLayout.() -> Unit) = ankoView({ CoordinatorLayout(it) },init)
但是我不认为它在任何地方都有解释.()意味着...
but I don't think it was explained anywhere what .() means...
推荐答案
T.() -> Unit
是带有接收方的扩展功能类型.
T.() -> Unit
is an extension function type with receiver.
除普通功能外,Kotlin还支持扩展功能.这种功能与普通功能的不同之处在于它具有接收器类型规范.这是通用的T.
部分.
Besides ordinary functions, Kotlin supports extension functions. Such function differs from an ordinary one in that it has a receiver type specification. Here it's a generic T.
part.
扩展函数中的this
关键字对应于接收器对象(在点之前传递的对象),因此您可以直接调用其方法(仍然可以从父作用域引用this
.带有限定符).
The this
keyword inside an extension function corresponds to the receiver object (the one that is passed before the dot), so you can call its methods directly (referring to this
from parent scopes is still possible with qualifiers).
功能with
是标准功能,是的.当前代码:
Function with
is a standard one, yes. It's current code:
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#with).
*/
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
因此它是T
和R
的通用函数,其第一个参数"receiver"的类型为T
,第二个参数"c8>的扩展功能类型,扩展了T
,返回的类型为R
依次由with
返回.
So it's a generic function for T
and R
, with first argument "receiver" of type T
and second, f
of extension function type, which extends T
, returning type R
which in turn returned by the with
.
例如,您可以像这样使用它:
For example, you can use it like this:
val threadInfoString = with (Thread.currentThread()) {
// isDaemon() & getPriority() are called with new property syntax for getters & setters
"${getName()}[isDaemon=$isDaemon,priority=$priority]"
}
有关扩展功能的信息,请参见此处:
kotlinlang.org/docs/reference/lambdas.html#extension-function-表达式
kotlinlang.org/docs/reference/scope-functions.html#with
kotlinlang.org/docs/reference/extensions.html
See documentation for extension functions here:
kotlinlang.org/docs/reference/lambdas.html#extension-function-expressions
kotlinlang.org/docs/reference/scope-functions.html#with
kotlinlang.org/docs/reference/extensions.html
已添加:
所以唯一有效的
f
是为T定义的任何0参数函数吗?
So the only valid
f
would be any 0-argument function defined for T?
并非如此.在Kotlin中功能类型和扩展功能类型是统一的,以便它们可以互换使用.例如,我们可以在需要函数(String) -> Int
的地方传递String :: length.
Not really. In Kotlin function types and extension function types are unified, so that they can be used interchangeably. For example, we can pass String::length where a function (String) -> Int
is expected.
// map() expects `(String) -> Int`
// argument has type `String.() -> Int`
strings.map(String::length)
Thread.() -> String
& (Thread) -> String
从后台来看是相同的–实际上,接收方是第一个参数.
Types like Thread.() -> String
& (Thread) -> String
are the same from the background side – receiver, in fact, is the first argument.
因此,以下任何函数均适合Thread.() -> String
参数:
So any of the following functions is suitable for 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
或者您可以简单地使用函数文字({}
),就像在threadInfoString
的示例中一样,但是它只能在可以从上下文中推断出接收器类型时起作用.
Or you can simply use function literal ({}
) as in the example with threadInfoString
, but it works only when the receiver type can be inferred from the context.
这篇关于带T.()的Kotlin函数签名是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!