带T.()的Kotlin函数签名是什么意思? [英] What does a Kotlin function signature with T.() mean?

查看:382
本文介绍了带T.()的Kotlin函数签名是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

因此它是TR的通用函数,其第一个参数"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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆