1

在java中我们使用分号,编译器在分号的基础上理解语句的结尾。

Kotlin也使用 JVM 编译器如何理解这是没有分号的语句的结尾Kotlin

4

4 回答 4

1

补充答案

TruncatedSemanticWhitespaceAwarePsiBuilderKotlin词法分析器在基于换行符对纯文本代码进行标记方面足够聪明。

无需插入(或用分号替换它们)即可完成此换行识别。在这里查看讨论

SemanticWhitespaceAwarePsiBuilderImpl是这个接口的一个实现,它有newlineBeforeCurrentToken()方法,它提供了一些关于它是如何工作的线索:

@Override
public boolean newlineBeforeCurrentToken() {
    if (!newlinesEnabled.peek()) return false;

    if (eof()) return true;

    // TODO: maybe, memoize this somehow?
    for (int i = 1; i <= getCurrentOffset(); i++) {
        IElementType previousToken = rawLookup(-i);

        if (previousToken == KtTokens.BLOCK_COMMENT
                || previousToken == KtTokens.DOC_COMMENT
                || previousToken == KtTokens.EOL_COMMENT
                || previousToken == SHEBANG_COMMENT) {
            continue;
        }

        if (previousToken != TokenType.WHITE_SPACE) {
            break;
        }

        int previousTokenStart = rawTokenTypeStart(-i);
        int previousTokenEnd = rawTokenTypeStart(-i + 1);

        assert previousTokenStart >= 0;
        assert previousTokenEnd < getOriginalText().length();

        for (int j = previousTokenStart; j < previousTokenEnd; j++) {
            if (getOriginalText().charAt(j) == '\n') {
                return true;
            }
        }
    }

    return false;
}

每当需要检查令牌时都会调用它:

private boolean tokenMatches(IElementType token, IElementType expectation) {
    if (token == expectation) return true;
    if (expectation == EOL_OR_SEMICOLON) {
        if (eof()) return true;
        if (token == SEMICOLON) return true;
        if (myBuilder.newlineBeforeCurrentToken()) return true;
    }
    return false;
}

因此,newlineBeforeCurrentToken()逐个字符解析并与换行符进行比较,最终返回 true 表示它是一个完整的语句。

于 2021-07-26T07:38:49.477 回答
1

如此处所述,

在 Kotlin 中,分号是可选的,因此换行很重要。

这本质上意味着kotlinc可以以与相同的方式识别语句的结尾javac,唯一的区别是标记语句结尾的字符,其中javac查找;kotlinc将查找\n(换行符)。

请注意,在 kotlin 中声明枚举类时需要使用分号。

例如,如果省略分号,以下代码将无法编译

enum class Fruit(val price: Double) {
    MANGO(100.0);

    fun printPrice(){
        print(price)
    }
} 
于 2021-07-26T06:35:39.777 回答
1

分号不会为代码添加任何对人类有价值的意义。生命太短暂,不能打扰他们。这只是 Java 中许多非必要复杂性示例中的一个(当然是次要的),这些示例已被更现代的 JVM 语言删除。

于 2021-07-26T07:58:08.543 回答
0

在 Kotlin 中,分号是可选的,但换行符很重要。

Kotlin 编译器通常会识别语句的结尾,即使没有显式 ; - 例如通过换行符。

重要 如果您想在一行中记录多个语句,它们之间用 ; 分隔。例如 :

    val a = 42 ; println(a)
于 2021-07-26T05:54:38.520 回答