在Kotlin中,函数声明语法允许在花括号前写等号.

考虑这两个例子:

  1. 没有=号标志:
fun foo1() {
    println("baz1")
}

体内的代码只需调用foo1()即可执行.

  1. With = sign:
fun foo2() = {
    println("baz2")
}

Here, when foo2() is called, nothing happens, but to get the body executed one can write foo2()().

这两个声明和why do they behave differently?有什么区别

可以使用以下程序运行代码:

fun main() {
    foo1()
    foo2()
}

/*
This code example produces the following results:
baz1
*/

This question, though having not much meaning, is [intentionally asked and answered by the author][1], because a few questions have already been posted where people got problems because of incorrect function definitions.

推荐答案

Despite visual similarity, the idea of these two declarations is completely different.

1.不带等号的函数声明

没有等号的函数声明是Unit-returning function(类似于Java的void个函数).

花括号内是它的主体,在函数调用时立即执行.可以使用明确指定的Unit重写函数:

fun foo1(): Unit {
    println("baz1")
    return Unit
}

Kotlin不需要Unit个返回函数的return语句和显式返回类型,而且通常都会被省略.

2.带等号的函数声明

带等号的函数声明是single-expression function,它所做的就是返回等号右边的内容.

一个更简单的例子:fun getInt() = 1只是fun getInt(): Int { return 1 }的缩写形式.

foo2中,右手边是a lambda.lambda代码块中的代码是not executed.换句话说,foo2是一个返回另一个函数的函数.

Return type of foo2 is () -> Unit, a function itself, and thus foo2 is a higher-order function.

没有语法糖和显式类型,foo2可以重写为

fun foo2(): () -> Unit {
    val result: () -> Unit = { println("baz2") }
    return result
}

As to the usage, the function which foo2 returns can be stored in a variable, passed around and can later be invoked:

val f = foo2()
f() //equivalent to
f.invoke()

This is also why foo2()() in the example executes the code from the lambda body.

Alternatively, we can add () at the end when we declare foo2(), as shown in the following example. As such, the lambda expression will be invoked when calling foo3(). But this is not a good pattern.

fun foo3() = {
    println("baz3")
}()

Kotlin相关问答推荐

当通过firstOrders访问时,存储在伴随对象中的对象列表具有空值

Kotlin多平台(KMP)保存到文件不能在iOS上保存

可以从背景图像中点击图标吗?

如何修改muableStateMapOf的值?

在 map 中查找键与在 kotlin 中查找 firstOrNull

有没有什么方法或算法可以在没有存储的情况下生成唯一的随机数?

Kotlin:我可以将函数分配给 main 的伴随对象中的变量吗?

Lets plot Kotlin中的多轴比例

kotlin 单例异常是好是坏?

如何在 Kotlin 中使用 volatile

如何在 Kotlin 文件中的 Android Studio 中控制何时将 Imports 替换为通配符

Kotlin - 覆盖方法中的 IllegalArgumentException

如何在 kotlin 中生成 json 对象?

如何解决:将Java类转换为Kotlin后出现error: cannot find symbol class ...?

参数不匹配;SimpleXML

Java Integer.MAX_VALUE 与 Kotlin Int.MAX_VALUE

Kotlin数据类打包

Kotlin扩展函数与成员函数?

使用 rxbinding 时我应该取消订阅吗?

如何在 firebase 数据库中使用 kotlin 协程