这是一个标准的 Kotlin 函数(据我所知)
inline fun<T> with(t: T, body: T.() -> Unit) { t.body() }
但是任何人都可以用简单的英语写下签名的确切含义吗?它是 T 的通用函数,第一个参数为“t” T 类型的第二个,函数类型的“主体”,接受 ????并且什么都不返回(单位)
我看到了这个符号Something.() -> 经常使用Something,即用于Anko:
inline fun Activity.coordinatorLayout(init: CoordinatorLayout.() -> Unit) = ankoView({ CoordinatorLayout(it) },init)
但我认为任何地方都没有解释 .() 的含义...
最佳答案
T.() -> Unit
是一个带有receiver的扩展函数类型。
除了普通函数,Kotlin 还支持扩展函数。这种函数与普通函数的不同之处在于它具有接收器类型规范。这是一个通用的 T.
部分。
扩展函数内部的this
关键字对应于receiver对象(在点之前传递的那个),所以你可以直接调用它的方法(引用this
仍然可以从父作用域 with qualifiers )。
with
函数是标准函数,是的。这是当前代码:
/**
* 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
的通用函数,第一个参数“接收器”类型为 T
,第二个参数为 f
的扩展函数类型,它扩展了 T
,返回类型 R
又由 with
返回。
例如,你可以这样使用它:
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-expressions
kotlinlang.org/docs/reference/scope-functions.html#with
kotlinlang.org/docs/reference/extensions.html
添加:
So the only valid
f
would be any 0-argument function defined for T?
不是真的。在 Kotlin function types and extension function types are unified , 以便它们可以互换使用。例如,我们可以在期望函数 (String) -> Int
的地方传递 String::length。
// map() expects `(String) -> Int`
// argument has type `String.() -> Int`
strings.map(String::length)
Thread.() -> String
& (Thread) -> String
这样的类型从后台看是一样的——receiver,其实就是第一个参数.
所以以下任何一个函数都适用于 Thread.() -> String
参数:
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
或者您可以简单地使用 function literal ({}
) 与 threadInfoString
的示例中一样,但它仅在可以从上下文中推断出接收器类型时才有效。
https://stackoverflow.com/questions/33190613/
相关文章:
android - 带有命名参数的 Kotlin 中的 Dagger 2 构造函数注入(inject
java - Kotlin 文件是否应该放在 Android 中的单独源目录中?
intellij-idea - 为什么 IntelliJ 建议将调用链转换为序列?
java - isInitialized - lateinit var 的支持字段此时不可访问
android - 抑制 "Identifier not allowed in Android"
java - Smartcast 是不可能的,因为属性有开放的或自定义的 getter