有趣的 Kotlin 0x01:Scala-like functions

Posted OpenCV or Android

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有趣的 Kotlin 0x01:Scala-like functions相关的知识,希望对你有一定的参考价值。

上一篇文章与大家分享了最近在 http://portal.kotlin-academy.com/#/ 上看到很多关于 Kotlin 的有趣的题目。个人觉得很适合 Kotlin 爱好者,感兴趣的小伙伴可自行查阅。【有趣的 Kotlin 】系列记录自己对每一题的理解。

0x01:Scala-like functions

fun hello() = {
    println("Hello, World")
}

fun main(args: Array<String>) {
    hello()
}

以上代码,运行结果为何?可选项:

  1. Does not compile
  2. Prints "Hello, World"
  3. Nothing
  4. Something else

思考一下,记录下你心中的答案。

分析

其实问题主要集中在 hello() 函数的理解上,题中:

fun hello() = {
    println("Hello, World")
}

而我们常见的函数的写法是这样的:

fun hello() {
    println("Hello, World")
}

两者相比,题中多出来一个 =  号,这就让两个函数有了本质上的差异。先看下我们常见的不带等号的写法:

fun hello() {
    println("Hello, World")
}
  • 函数名:hello
  • 函数参数:无
  • 返回值: Unit

再看带等号的题中的写法:

fun hello() = {
    println("Hello, World")
}
  • 函数名:hello
  • 函数参数:无
  • 返回值: ???

这个函数的返回类型是啥 ?我们先看一个例子:

fun isPositive(number: Int) =  number > 0

同样是 =,但是后面跟的内容不一样,number > 0 是一个表达式,由于根据表达式可以推断出返回类型,这里就省略了返回值  Boolean

对比上面题中 hello 函数的写法,其实也是一种省略了返回值类型的简略写法。先看等号后跟的内容

= {
    println("Hello, World")
}

其实就是一个 Lambda 表达式,而 Lambda 表达式是函数类型实例化的一种方式,所以 hello 函数的返回值是一个函数类型,且函数类型为 () Unit。这样答案就很明显了。我们把返回类型补全后,题目内容变为:

fun hello(): () -> Unit = {
    println("Hello, World")
}

fun main(args: Array<String>) {
    hello()
}

main 函数中调用 hello 函数只是返回一个函数类型实例,并没有调用这个函数类型实例,所以 “Hello, World” 是不会打印的。那么,

正确答案为:3. Nothing。

倘若我们想打印 “Hello, World”  该如何修改呢?三种方式:

  • 第一种:去掉 hello 函数定义中的等号
fun hello() {
    println("Hello, World")
}
fun main(args: Array<String>) {
    hello()
}
  • 第二种:通过操作符 () 调用函数类型实例
fun hello() = {    
    println("Hello, World")
}
fun main(args: Array<String>) { 
    hello()()
}
  • 第三种:通过操作符 invoke 调用函数类型实例
fun hello() = {
    println("Hello, World")
}

fun main(args: Array<String>) {
    hello().invoke()
}

  

  推荐阅读: