语法 – Kotlin中的分号推理规则是什么?

Kotlin provides “semicolon inference”: syntactically, subsentences (e.g., statements, declarations etc) are separated by the pseudo-token SEMI, which stands for “semicolon or newline”. In most cases, there’s no need for semicolons in Kotlin code.

这就是grammar页面所说的内容.这似乎暗示在某些情况下需要指定分号,但它没有指定它们,并且下面的语法树并不能完全证明这一点.此外,我怀疑在某些情况下此功能可能无法正常工作并导致问题.

所以问题是什么时候应该插入一个分号?为了避免编写错误的代码,需要注意哪些角落情况?

您只需要在编译器与您尝试执行的操作不明确的情况下指定分号,并且缺少分号将导致明显的编译器错误.

规则是:不要担心这一点,根本不使用分号(除了以下两种情况).保证,编译器会告诉您何时出错.即使您不小心添加了一个额外的分号,语法突出显示也会显示“冗余分号”警告是不必要的.

分号的两种常见情况:

枚举类具有枚举列表以及枚举中的属性或函数,需要一个;在枚举列表之后,例如:

enum class Things {
    ONE, TWO;

    fun isOne(): Boolean = this == ONE
}

在这种情况下,编译器会直接告诉您是否未能正确执行:

Error:(y, x) Kotlin: Expecting ‘;’ after the last enum entry or ‘}’ to close enum class body

否则唯一的另一种常见情况是当你在同一行上做两个语句时,可能为了简洁起见:

myThingMap.forEach { val (key, value) = it; println("mapped $key to $value") }

在最后一个例子中没有分号会让你在你正在做的事情上感到困惑时会出现一个更加神秘的错误.很难使一些代码既有效又可用作分号分隔的两个语句,当分号被删除并且它们成为一个分号时也是有效的.

在过去,还有其他一些情况,例如类的初始化块在Kotlin 1.0之前更加“匿名”{…},之后变为init {…},不再需要分号,因为它更清晰.这些案件不再保留在该语言中.

对此功能的信心:

Also I have suspicions that there are some cases where this feature may not work correctly and cause problems.

该功能运行良好,没有任何证据证明此功能存在任何问题,多年的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() }
    }
}

在这种情况下,doStuff被分配调用的结果(“message”){doNothing()},它是type() – > Unit的函数;如果你添加一个分号,它将被赋予函数{doNothing()},它也是type() – > Unit.因此代码在两个方面都是有效的.但我没有看到这样的事情自然发生,因为一切都必须完美排列. feature suggested emit keyword or ^ hat operator会使这个案例变得不可能,并且由于强烈反对意见和时间限制,它被认为是在1.0之前下降.

相关文章
相关标签/搜索