分号推理的规则是什么? [英] What are the rules of semicolon inference?

查看:129
本文介绍了分号推理的规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Kotlin提供分号推断":从句法上讲,用伪令牌SEMI分隔句子(例如,语句,声明等),SEMI代表分号或换行符".在大多数情况下,不需要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.

这是语法页面所说的.这似乎暗示在某些情况下需要指定分号,但未指定分号,并且下面的语法树并不能完全使分号清晰可见.我也怀疑在某些情况下此功能可能无法正常工作并引起问题.

This is what the grammar page says. This seems to imply that there is a need to specify semicolons in some cases, but it doesn't specify them, and the grammar tree below doesn't exactly make this obvious. Also I have suspicions that there are some cases where this feature may not work correctly and cause problems.

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

So the question is when should one insert a semicolon and what are the corner cases one needs to be aware of to avoid writing erroneous code?

推荐答案

只有在编译器对您要执行的操作有歧义的情况下,才需要指定分号,并且缺少分号会导致明显的问题.编译器错误.

You only need to specify semicolons in cases where it is ambiguous to the compiler what you are trying to do, and the absence of a semicolon would result in an obvious compiler error.

规则是:不用担心,也不要使用分号(以下两种情况除外).保证,编译器会在出现错误时告诉您.即使您不小心添加了多余的分号,语法高亮也会显示出不必要的警告冗余分号".

The rule is: Don't worry about this and don't use semicolons at all (other than the two cases below). The compiler will tell you when you get it wrong, guaranteed. Even if you accidentally add an extra semicolon the syntax highlighting will show you it is unnecessary with a warning of "redundant semicolon".

分号的两种常见情况:

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

An enum class that has a list of enums and also properties or functions in the enum requires a ; after the enum list, for example:

enum class Things {
    ONE, TWO;

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

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

And in this case the compiler will tell you directly if you fail to do it correctly:

错误:(y,x)Kotlin:期待';'在最后一个枚举条目或}"之后关闭枚举类主体

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

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

Otherwise the only other common case is when you are doing two statements on the same line, maybe for brevity sake:

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

在最后一个示例中,如果缺少分号,则会在混淆您所做的工作时给您带来一个更加神秘的错误.确实很难编写同时作为两个由分号分隔的语句的有效代码,这些语句在分号被删除并变为一个时也有效.

Absence of a semicolon in this last example will give you a more mysterious error at the point where it is confused what you are doing. It is really hard to make some code that would both be valid as two statements separated by a semicolon that are also valid when the semicolon is removed and they become one.

过去还有其他情况,例如类的初始化块在Kotlin 1.0之前更匿名" { ... },后来成为init { ... },不再需要使用分号,因为它更清晰.这些案例不再保留在语言中.

In the past there were other cases like an initialization block of a class which was more "anonymous" { ... } before Kotlin 1.0 and later became init { ... } which no longer needed the semicolon because it is much clearer. These cases no longer remain in the language.

对此功能的信心:

我还怀疑在某些情况下此功能可能无法正常工作并引起问题.

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

该功能运行良好,没有证据表明该功能存在问题,并且多年的Kotlin经验并未发现该功能适得其反的任何已知情况.如果缺少;出现问题,则编译器将报告错误.

The feature works well, there is no evidence anywhere that there are problems with this feature and years of Kotlin experience have not turned up any known cases where this feature backfires. If there is a problem with a missing ; the compiler will report an error.

在搜索我所有的开源Kotlin以及我们内部的大型Kotlin项目时,除上述情况外,我没有发现其他分号-总数很少.支持不要在Kotlin中使用分号"这一概念.

Searching all of my open-source Kotlin, and our internal rather large Kotlin projects, I find no semi-colons other than the cases above -- and very very few in total. Supporting the notion of "don't use semicolons in Kotlin" as the rule.

但是,有可能您故意设计了一个编译器没有报告错误的情况,因为您创建的代码有效且具有和不具有分号的含义都不同.如下所示(@Ruckus答案的修改版本):

However, it is possible that you can intentionally contrive a case where the compiler doesn't report an error because you created code that is valid and has different meaning with and without a semicolon. This would look like the following (a modified version of the answer by @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分配了对whatever("message") { doNothing() }的调用结果,这是类型为()->Unit的函数;如果添加分号,则会为其分配功能{ doNothing() },该功能也属于类型()->Unit.因此,代码在两种情况下均有效. 但是我没有看到这样的事情自然发生,因为一切都必须完美地结合在一起. 功能建议的emit关键字或^帽子操作符将使这种情况无法实现,并且由于强烈反对意见和时间限制,该版本已被考虑但在1.0之前下降.

In this case doStuff is being assigned the result of the call to whatever("message") { doNothing() } which is a function of type ()->Unit; and if you add a semicolon it is being assigned the function { doNothing() } which is also of type ()->Unit. So the code is valid both ways. But I have not seen something like this occur naturally since everything has to line up perfectly. The feature suggested emit keyword or ^ hat operator would have made this case impossible, and it was considered but dropped before 1.0 due to strongly oposed opinions and time constraints.

这篇关于分号推理的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆