这是一个标准的Kotlin函数(据我所知)

inline fun<T> with(t: T, body: T.() -> Unit) { t.body() }

但是有没有人能用简单的英语写出这个签名到底是什么意思?它是T的泛型函数,第一个参数为"t" 类型T的函数类型,第二个是函数类型的"Body",接受?函数.并且不返回任何内容(单位)

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 is an extension function type with receiver.

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.

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


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()

它是TR的泛型函数,第一个参数"Receiver"类型为T,第二个参数f为扩展函数类型f,扩展函数类型为T,返回类型R,而类型Rwith返回.

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]"
}


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


Added:

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从背景方面看是一样的——事实上,接收器是第一个参数.

因此,以下任何函数都适用于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

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.

Kotlin相关问答推荐

Kotlin中一个接口的实现问题

kotlin - 挂起简单方法调用链时可能存在冗余分支

合并状态流

如何在数据类中删除空格 (String)?

限制通用Kotlin枚举为特定类型

在 kotlin 中使具体化字段可选

Kotlin 编译器在构造函数中报告未使用的表达式,以便构建器采用 vararg lambda

Kotlin 插件之间的区别

Kotlin:查找集合中最常见的元素

Kotlin 方法重载

如何将超过 2 个 api 调用的结果与 Coroutines Flow 结合起来?

如何用 kotlin 打包 List

Kotlin:如何在活页夹中返回正在运行的服务实例?

如何设置两列recyclerview?

如何在 Spring WebFlux 的响应正文中流式传输二进制数据

在 Kotlin 中实现 (/inherit/~extend) 注解

Kotlin内联扩展属性

创建Spring和#180的实例;Kotlin中的参数化类型引用

在 kotlin 中,如何将主构造函数中的属性设置器设为私有?

从另一个列表创建一个列表