Kotlin 学习笔记,2019-11-12

前情提要:这个笔记原本是记录在知乎上的,然而中间因为各种原因已经中断半年了。想要恢复的时候,却发现知乎网页端访问
各种坑,而且那边也一直不支持 Markdown,所以换到简书来试一下。

上期笔记


Basic Types: Numbers, Strings, Arrays​

基本类型一节没有什么意外的地方,内容很简单。比较喜欢的一个点是不同宽度的数字类型之间不能隐式转换;不太喜欢的一点是,操作运算符重载依然支持 "abc" + 1 + "def" 这种字符串和数字之间的隐式转型 + 直接拼接。

另外,字符类型这一章简单提了一下支持 unicode,但是没有解释详情。网页上尝试了一下,直接 println('我') 这样打印中文字符不工作。

2020-06-14 补充说明,这一点最后证明是网页版环境的问题,本地安装 IDE 之后执行这个毫无问题。

最后还是 JVM 的限制,基本类型进入泛型容器需要装箱,性能受害。这个问题导致一堆 IntArray,CharArray,FloatArray 之类的定制版本容器的存在,看的很蛋疼。讲真 Kotlin 这么多语法糖,为啥不在这里语法糖一下 ……


Packages and Imports

很简单的一节。Kotlin 的 package 和文件所在目录不绑定,类名和文件名似乎也不绑定(待确认),这样方便些。另外 import xxx as yyy 这个别名特性不错,Java 你赶紧支持一下好吗!


Control Flow

这一节有点意思。文档两次强调 if 和 when 可以是语句也可以是表达式,引发了我的几个小问题:

  1. Kotlin 语句是怎么分割的?没看到分号,不知道是真的语法设计上考虑过了不需要,还是象 Go 那样语法上有,但是一般情况可以省略(以及特殊情况下必须恶心地手工加上)?
  2. 这两种表达式的类型是怎么定义的?if ... else 两个分支的类型不同怎么处理?
  3. 表达式可以带副作用显然是题中应有之义了。

Returns and Jumps​

这一节有点惊讶。这个 return 上面玩出这么多花样感觉挺奇怪的,尤其是下面这个例子:

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return // non-local return directly to the caller of foo()
        print(it)
    }
    println("this point is unreachable")
}

这个函数中 forEach 执行的 lambda 表达式中包含一个 return,执行到的话会直接退出整个函数,需要用 return 到一个 label 来避开 …… 不太明白这么设计背后的动机是什么。单纯为了「return 会退出 enclosing 的函数定义而这里是个 lambda 表达式」这种定义一致性上的需求?感觉 Kotlin 这个语法糖放到齁的设计团队不象有这个洁癖啊?

另外我试了一下这个:

fun foo() {
    val x = listOf(1, 2, 3, 4, 5).map {
        if (it == 3) return@map // local return to the caller of the lambda, i.e. the forEach loop
        it * 2
    }
    println(x)
    println(" done with implicit label")
}

结果是:

[kotlin.Unit, kotlin.Unit, kotlin.Unit, kotlin.Unit, kotlin.Unit]
 done with implicit label

可惜不能玩一个 list 映射做一半,XD

当然有一句说一句,break 可以带 label 退出多重循环这个,还是有一点用的 …… 好吧只有一点点,个人认为多重循环本身已经算是个坏味道了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。