泛型类型的扩展功能

时间:2019-02-17 19:40:56

标签: kotlin kotlin-extension kotlin-function-type

我是Kotlin的新手,我试图了解类型别名和函数。
我有以下示例:

interface EmptyInterface
typealias GenericCase<T> = T.(EmptyInterface) -> T

val myFunctionVariable: GenericCase<String> = {
    _ -> "Hello world!"
}

到目前为止,我的理解是,我扩展了T定义的函数,该函数接受EmptyInterface作为参数并返回T。 因此,myFunctionVariable是一个传递EmptyInterface

的函数。

但是以下代码无法编译

class a: EmptyInterface
println("${myFunctionVariable(a())}")  

我需要传递一个String作为第一个参数:

class a: EmptyInterface
println("${myFunctionVariable("",a())}")

为什么需要字符串作为第一个参数? T.(EmptyInterface) -> T(在本例中为String.(EmptyInterface) -> String)只有1个参数。 有人可以解释一下吗?

2 个答案:

答案 0 :(得分:1)

类型T.中的T.(EmptyInterface) -> T表示此功能是T上的扩展功能。因此,调用此函数的常规方法是获取一个T实例,并在该实例上对其进行调用,就好像它是成员函数一样。在您的示例中,您选择T作为String,则必须在String实例上调用该函数:

"foo".myFunctionVariable(a())

您使用的语法是调用此扩展名的另一种方法,将接收方当作函数的第一个参数(实际上在字节码级别是)传递给接收方:

myFunctionVariable("foo", a())

但是,如果您希望将函数与这种语法一起使用,则最好将其声明为带有两个参数,因为扩展函数的这种调用可能非常意外。

(有关如何在类型上的扩展的函数和将其作为this answer中的第一个参数的函数之间来回移动的更多信息。

答案 1 :(得分:1)

在类型T.(EmptyInterface) -> T中,第一个T receiver :调用该函数的实例,该实例在函数内变为this定义。 (类似于扩展功能。)

有效地,接收器成为该函数的隐藏的第一个参数;如您所发现的,如果您尝试直接调用该函数,则需要显式提供它。

其语言规范为here;一些other answers可能也有帮助。