kotlin - 带有 T.() 的 Kotlin 函数签名是什么意思?

这是一个标准的 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()

所以它是 TR 的通用函数,第一个参数“接收器”类型为 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 - getActionView 已弃用?

java - Kotlin 文件是否应该放在 Android 中的单独源目录中?

intellij-idea - 为什么 IntelliJ 建议将调用链转换为序列?

java - isInitialized - lateinit var 的支持字段此时不可访问

android - 抑制 "Identifier not allowed in Android"

string - 字符串中的美元符号字符

java - Smartcast 是不可能的,因为属性有开放的或自定义的 getter

java - 在 Kotlin 中使用 Room 的 @ForeignKey 作为 @Entity

kotlin - 如何使用 Gradle Kotlin 脚本创建胖 JAR?