Jay*_*ard 20
您只需要在编译器与您尝试执行的操作不明确的情况下指定分号,并且缺少分号将导致明显的编译器错误.
规则是:不要担心这一点,根本不使用分号(除了以下两种情况).编译器会在你弄错的时候告诉你,保证.即使您不小心添加了一个额外的分号,语法突出显示也会显示"冗余分号"的警告是不必要的.
分号的两种常见情况:
具有枚举列表以及枚举中的属性或函数的枚举类需要;在枚举列表之后,例如:
enum class Things {
ONE, TWO;
fun isOne(): Boolean = this == ONE
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,编译器会直接告诉您是否未能正确执行此操作:
错误:(y,x)Kotlin:期待';' 在最后一次枚举输入之后或'}'关闭枚举类本体
否则唯一的另一种常见情况是当你在同一行上做两个语句时,可能为了简洁起见:
myThingMap.forEach { val (key, value) = it; println("mapped $key to $value") }
Run Code Online (Sandbox Code Playgroud)
在最后一个例子中没有分号会给你一个更加神秘的错误,因为它让你感到困惑.很难使一些代码既有效又可用作分号分隔的两个语句,当分号被删除并且它们成为一个分号时也是有效的.
在过去,还有其他一些案例,例如类的初始化块,{ ... }在Kotlin 1.0之前更加"匿名" ,后来变得init { ... }不再需要分号,因为它更清晰.这些案件不再保留在该语言中.
对此功能的信心:
此外,我怀疑在某些情况下此功能可能无法正常工作并导致问题.
该功能运行良好,没有任何证据证明此功能存在任何问题,多年的Kotlin经验未发现此功能适用的任何已知情况.如果缺少问题,;编译器将报告错误.
搜索我的所有开源Kotlin以及我们内部相当大的Kotlin项目,我发现除了上述情况之外没有分号 - 而且总共非常少.支持"不要在Kotlin中使用分号"的概念作为规则.
但是,您可以有意设计编译器不报告错误的情况,因为您创建的代码有效且具有不同分数的含义.这看起来如下(@Ruckus的答案的修改版本):
fun whatever(msg: String, optionalFun: ()->Unit = {}): () -> Unit = ...
val doStuff: () -> Unit = when(x) {
is String -> {
{ doStuff(x) }
}
else -> {
whatever("message") // absence or presence of semicolon changes behavior
{ doNothing() }
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,doStuff被赋予调用的结果,该调用 whatever("message") { doNothing() }是类型的函数()->Unit; 如果你添加一个分号,它将被赋予{ doNothing() }同样类型的函数()->Unit.因此代码在两个方面都是有效的. 但我没有看到这样的事情自然发生,因为一切都必须完美排列.该功能建议emit的关键字或^帽子运营会作出这种情况下是不可能的,它被认为但由于强烈oposed意见和时间的限制降至1.0之前.
除了Jayson Minard的回答之外,我还遇到了另一个奇怪的边缘情况,需要一个分号.如果您在不使用return语句的情况下返回函数的语句块中,则需要使用分号.例如:
val doStuff: () -> Unit = when(x) {
is String -> {
{ doStuff(x) }
}
else -> {
println("This is the alternate"); // Semicolon needed here
{ doNothing() }
}
}
Run Code Online (Sandbox Code Playgroud)
没有分号,Kotlin认为该{ doNothing() }语句是第二个参数,println()编译器报告错误.
科特林似乎主要是热切地推断分号.似乎有例外(如Jayson Minard的枚举示例所示).
通常,类型系统将捕获严重推断的分号,但是在某些情况下编译器会失败.
如果调用的参数在下一行(包括括号)中,Kotlin将假定参数只是一个新的带括号的表达式语句:
fun returnFun() : (x: Int) -> Unit {
println("foo")
return { x -> println(x) }
}
fun main(args: Array<String>) {
println("Hello, world!")
returnFun()
(1 + 2) // The returned function is not called.
}
Run Code Online (Sandbox Code Playgroud)
更常见的情况可能是以下情况,我们在下一行中返回表达式.大多数情况下类型系统会抱怨没有返回值,但如果返回类型是Unit,那么所有的赌注都是关闭的:
fun voidFun() : Unit {
println("void")
}
fun foo() : Unit {
if (1 == 1) return
voidFun() // Not called.
}
fun bar() : Unit {
if (1 == 1)
return
voidFun() // Not called.
}
Run Code Online (Sandbox Code Playgroud)
bar如果return voidFun()不适合一行,该功能可能会发生.也就是说,开发人员必须简单地在单独的行上写入对函数的调用.
| 归档时间: |
|
| 查看次数: |
5297 次 |
| 最近记录: |