正常功能和表达功能之间的差异

时间:2018-05-28 06:51:51

标签: kotlin

我们已经知道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"

请你帮我理解一下。

3 个答案:

答案 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)

我们可以略微重写py的定义而不改变其含义:

fun p() {
    println( "Hello p")
}

fun y() = {
    println( "Hello y")
}

请注意,语法几乎完全相同(=会有所不同),这有点不幸,因为py是完全不同的野兽。

  • fun p是一个函数声明。 p不接受任何参数并返回Unit
  • fun y是一个函数声明。 y不接受参数并返回函数,其类型为() - >单位

因为对y()的调用会返回一个函数,您需要调用那个函数来打印它:y()()

以上所有内容并未对py本身的类型说太多 - 只是他们返回某些类型:

  • p的实际类型为KFunction0< Unit >
  • y的实际类型为KFunction0< () -> Unit >

如果你想更多地玩这个:-)考虑:

fun yy() = {
    ::p
}

您可以验证yy()()()打印hello p并且其类型为KFunction0<()->KFunction0<Unit>>