我们已经知道Kotlin中的所有函数都是类型,所以如果有这个函数:
fun p() : Unit
{
println("Hello P")
}
这只是一个没有参数并返回Unit的函数,所以我可以声明另一个执行相同操作的函数
fun y() : () -> Unit =
{
println("Hello Y")
}
但是当我运行这些功能时会有不同的结果
p() //--> will print out "Hello P"
y() //--> doesn't print out anything
但如果我用这种方式调用y():
y()() //--> will print out "Hello Y"
请你帮我理解一下。
答案 0 :(得分:4)
我们已经知道Kotlin中的所有功能都是类型
事实并非如此。有函数类型,函数类型实例和函数声明。这是函数的声明,其返回类型为\(
:
Unit
这是一种功能类型:
fun p() : Unit
{
println("Hello P")
}
这是函数的声明,其返回类型是函数类型() -> Unit
:
() -> Unit
调用fun y() : () -> Unit =
{
println("Hello Y")
}
执行print语句时,调用p()
只会返回一个函数实例,在调用时,它将执行print语句:
y()
在结构上,函数声明与具有函数类型的属性的声明非常相似:
y()()
从语法上讲,你可以用同样的方式使用它:
val x: () -> Unit =
{
println("Hello X")
}
您也可以将其传递给其他函数:
x()
但是你不能用函数声明做同样的事情:
fun higherOrderFun(block: () -> Unit) [
println("higher order")
block()
}
higherOrderFun(x)
这是因为功能声明不是"""你可以传播,它只是一个可执行代码的声明。
您还可以从函数声明中创建函数类型的实例:
higherOrderFun(p) // Compiler error
现在相当于::p
。实际上,你也可以写
x
现在你有了一个val x = ::p
实例,它只会立即调用x
并返回其值。
虽然函数声明和函数实例之间存在强烈的形式对称,并且甚至有只有后者的语言(例如,JavaScript或LISP),但前者在性能和内存使用方面更好。
答案 1 :(得分:3)
示例的返回类型
fun y() : () -> Unit =
{
println("Hello Y")
}
实际上是一个函数类型()->Unit
,因此当您调用它时,将返回此匿名函数而不调用它。你可以这样称呼它:
y()()
您可以做的是创建一个包含此function的变量:
val y = { println("Hello Y") }
简单地称之为:y()
答案 2 :(得分:1)
我们可以略微重写p
和y
的定义而不改变其含义:
fun p() {
println( "Hello p")
}
fun y() = {
println( "Hello y")
}
请注意,语法几乎完全相同(=
会有所不同),这有点不幸,因为p
和y
是完全不同的野兽。
fun p
是一个函数声明。 p
不接受任何参数并返回Unit fun y
是一个函数声明。 y
不接受参数并返回函数,其类型为() - >单位因为对y()
的调用会返回一个函数,您需要调用那个函数来打印它:y()()
以上所有内容并未对p
和y
本身的类型说太多 - 只是他们返回某些类型:
p
的实际类型为KFunction0< Unit >
y
的实际类型为KFunction0< () -> Unit >
如果你想更多地玩这个:-)考虑:
fun yy() = {
::p
}
您可以验证yy()()()
打印hello p
并且其类型为KFunction0<()->KFunction0<Unit>>