Kotlin 正规函数与表达式函数的区别

Kotlin 正规函数与表达式函数的区别,kotlin,Kotlin,我们已经知道Kotlin中的所有函数都是类型,因此如果有此函数: fun p() : Unit { println("Hello P") } fun higherOrderFun(block: () -> Unit) [ println("higher order") block() } higherOrderFun(x) 这只是一个没有参数并返回一个单位的函数,所以我可以声明另一个做同样事情的函数 fun y() : () -> Unit =

我们已经知道Kotlin中的所有函数都是类型,因此如果有此函数:

    fun p() : Unit 
{
    println("Hello P")
}
fun higherOrderFun(block: () -> Unit) [
    println("higher order")
    block()
}

higherOrderFun(x)
这只是一个没有参数并返回一个单位的函数,所以我可以声明另一个做同样事情的函数

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"
你能帮我理解一下吗

我们已经知道Kotlin中的所有函数都是类型

事实并非如此。有函数类型、函数类型的实例和函数声明。这是返回类型为
Unit
的函数的声明:

fun p() : Unit 
{
    println("Hello P")
}
fun y() : () -> Unit = 
{
    println("Hello Y")
}
这是一种函数类型:

() -> Unit
val x: () -> Unit = 
{
    println("Hello X")
}
这是一个函数的声明,其返回类型为函数类型
()->Unit

fun p() : Unit 
{
    println("Hello P")
}
fun y() : () -> Unit = 
{
    println("Hello Y")
}
调用
p()
执行print语句,而调用
y()
只返回一个函数实例,调用该实例时将执行print语句:

y()()
从结构上讲,函数声明与具有函数类型的属性声明非常相似:

() -> Unit
val x: () -> Unit = 
{
    println("Hello X")
}
在语法上,您可以使用相同的方法:

x()
您还可以将其传递给另一个函数:

    fun p() : Unit 
{
    println("Hello P")
}
fun higherOrderFun(block: () -> Unit) [
    println("higher order")
    block()
}

higherOrderFun(x)
但是,对于函数声明,不能执行相同的操作:

higherOrderFun(p) // Compiler error
::p
这是因为函数声明不是可以传递的“东西”,它只是可执行代码的声明

您还可以通过函数声明创建函数类型的实例:

higherOrderFun(p) // Compiler error
::p
这现在相当于
x
。事实上,你也可以写作

val x = ::p
现在您有了一个实例
x
,它除了立即调用
p()
并返回其值之外,什么也不做

虽然函数声明和函数实例之间有很强的形式对称性,甚至有些语言只有后者(例如JavaScript或LISP),但前者在性能和内存使用方面更好

我们已经知道Kotlin中的所有函数都是类型

事实并非如此。有函数类型、函数类型的实例和函数声明。这是返回类型为
Unit
的函数的声明:

fun p() : Unit 
{
    println("Hello P")
}
fun y() : () -> Unit = 
{
    println("Hello Y")
}
这是一种函数类型:

() -> Unit
val x: () -> Unit = 
{
    println("Hello X")
}
这是一个函数的声明,其返回类型为函数类型
()->Unit

fun p() : Unit 
{
    println("Hello P")
}
fun y() : () -> Unit = 
{
    println("Hello Y")
}
调用
p()
执行print语句,而调用
y()
只返回一个函数实例,调用该实例时将执行print语句:

y()()
从结构上讲,函数声明与具有函数类型的属性声明非常相似:

() -> Unit
val x: () -> Unit = 
{
    println("Hello X")
}
在语法上,您可以使用相同的方法:

x()
您还可以将其传递给另一个函数:

    fun p() : Unit 
{
    println("Hello P")
}
fun higherOrderFun(block: () -> Unit) [
    println("higher order")
    block()
}

higherOrderFun(x)
但是,对于函数声明,不能执行相同的操作:

higherOrderFun(p) // Compiler error
::p
这是因为函数声明不是可以传递的“东西”,它只是可执行代码的声明

您还可以通过函数声明创建函数类型的实例:

higherOrderFun(p) // Compiler error
::p
这现在相当于
x
。事实上,你也可以写作

val x = ::p
现在您有了一个实例
x
,它除了立即调用
p()
并返回其值之外,什么也不做


虽然函数声明和函数实例之间有很强的形式对称性,甚至有些语言只有后者(例如JavaScript或LISP),但前者在性能和内存使用方面更好。

示例的返回类型

fun y() : () -> Unit = 
{
    println("Hello Y")

}
实际上是一个函数类型
()->单元
,因此当您调用它时,将返回此匿名函数而不调用它。你可以这样称呼它:

y()()
您可以改为创建一个包含以下内容的变量:


简单地这样称呼它:
y()
示例的返回类型

fun y() : () -> Unit = 
{
    println("Hello Y")

}
实际上是一个函数类型
()->单元
,因此当您调用它时,将返回此匿名函数而不调用它。你可以这样称呼它:

y()()
您可以改为创建一个包含以下内容的变量:


简单地这样称呼它:
y()

我们可以稍微重写
p
y
的定义,而不改变它们的含义:

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

fun y() = {
    println( "Hello y")
}
请注意,语法几乎相同(
=
产生了所有差异),这有点不幸,因为
p
y
是完全不同的

  • fun p
    是一个函数声明<代码>p不接受任何参数并返回单位
  • funy
    是一个函数声明
    y
    不接受任何参数并返回类型为()->Unit的函数
因为调用
y()
会返回一个函数,所以需要调用函数才能将其打印出来:
y()()

以上所有内容都没有说明
p
y
本身的类型,只是它们返回了某些类型:

  • p
    的实际类型是
    KFunction0
  • y
    的实际类型是
    KFunction0<()->Unit>
如果您想进一步利用此功能:-)请考虑:

fun yy() = {
    ::p
}

您可以验证
yy()()()
打印
hello p
,其类型为
KFunction0KFunction0>
我们可以稍微重写
p
y
的定义,而不改变其含义:

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

fun y() = {
    println( "Hello y")
}
请注意,语法几乎相同(
=
产生了所有差异),这有点不幸,因为
p
y
是完全不同的

  • fun p
    是一个函数声明<代码>p不接受任何参数并返回单位
  • funy
    是一个函数声明
    y
    不接受任何参数并返回类型为()->Unit的函数
因为对
y()
的调用返回一个函数,所以需要invo