前情提要:这个笔记原本是记录在知乎上的,然而中间因为各种原因已经中断半年了。想要恢复的时候,却发现知乎网页端访问
各种坑,而且那边也一直不支持 Markdown,所以换到简书来试一下。
Basic Types: Numbers, Strings, Arrays
基本类型一节没有什么意外的地方,内容很简单。比较喜欢的一个点是不同宽度的数字类型之间不能隐式转换;不太喜欢的一点是,操作运算符重载依然支持 "abc" + 1 + "def"
这种字符串和数字之间的隐式转型 + 直接拼接。
另外,字符类型这一章简单提了一下支持 unicode,但是没有解释详情。网页上尝试了一下,直接 println('我')
这样打印中文字符不工作。
2020-06-14 补充说明,这一点最后证明是网页版环境的问题,本地安装 IDE 之后执行这个毫无问题。
最后还是 JVM 的限制,基本类型进入泛型容器需要装箱,性能受害。这个问题导致一堆 IntArray,CharArray,FloatArray 之类的定制版本容器的存在,看的很蛋疼。讲真 Kotlin 这么多语法糖,为啥不在这里语法糖一下 ……
很简单的一节。Kotlin 的 package 和文件所在目录不绑定,类名和文件名似乎也不绑定(待确认),这样方便些。另外 import xxx as yyy
这个别名特性不错,Java 你赶紧支持一下好吗!
这一节有点意思。文档两次强调 if 和 when 可以是语句也可以是表达式,引发了我的几个小问题:
- Kotlin 语句是怎么分割的?没看到分号,不知道是真的语法设计上考虑过了不需要,还是象 Go 那样语法上有,但是一般情况可以省略(以及特殊情况下必须恶心地手工加上)?
- 这两种表达式的类型是怎么定义的?if ... else 两个分支的类型不同怎么处理?
- 表达式可以带副作用显然是题中应有之义了。
这一节有点惊讶。这个 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 退出多重循环这个,还是有一点用的 …… 好吧只有一点点,个人认为多重循环本身已经算是个坏味道了。