Kotlin操作符?,,,?:开源实现

Kotlin操作符?,,,?:开源实现,kotlin,Kotlin,我是Kotlin的新手,我正在研究null-safety和Elvis操作符,希望了解更多关于如何在JVM上实现这些操作符的信息 我有兴趣了解以下各项的实施情况: ?。?: 但我无法找到任何与这些相关的来源。这些实现是隐藏的吗?从我的IDE中,我也找不到与这些相关的任何源,magic 从:它指定Kotlin是一种开放源代码语言:Kotlin是一种面向JVM、Android、JavaScript和本机的开放源代码静态类型编程语言 注意:我知道我不需要在Elvis的右侧指定null,这只是为了在屏幕

我是Kotlin的新手,我正在研究null-safety和Elvis操作符,希望了解更多关于如何在JVM上实现这些操作符的信息

我有兴趣了解以下各项的实施情况:

?:

但我无法找到任何与这些相关的来源。这些实现是隐藏的吗?从我的IDE中,我也找不到与这些相关的任何源,magic

从:它指定Kotlin是一种开放源代码语言:Kotlin是一种面向JVM、Android、JavaScript和本机的开放源代码静态类型编程语言


注意:我知道我不需要在Elvis的右侧指定null,这只是为了在屏幕抓取中传达我的观点。

免责声明:我不是Kotlin编译器的专家。我只是看了一下源代码

令牌定义如下:

KtSingleValueToken安全访问=新的KtSingleValueToken(“安全访问”),“?”;
KtSingleValueToken ELVIS=新的KtSingleValueToken(“ELVIS”、“?:”);
KtSingleValueToken任务=新的KtSingleValueToken(“任务”、“?”);
这些标记由Kotlin编译器本身解析,它们没有在Java中定义。这就是为什么不能跳转到定义-它们是由编译器重新编写的

我不知道它们是如何实现的,但查看Kotlin源代码并使用上述标记作为起点可能会很有用。

这些功能“嵌入”到该语言中。因此,您无法在编译时真正深入研究代码。与此类似的一个示例是尝试实现
while
循环或
when
语句。这些是只生成编译代码的语言特性

如果你好奇的话,你可以做的一件事就是用它们反编译一个简单的程序,并检查结果。然而,由于生成的字节码可能包含一些优化,因此不同用例的结果可能不同

你需要知道的最重要的事情是他们做什么如何使用他们。您可以在中找到空安全运算符和java代码之间等效行为的示例,其中包含此java代码

public void sendMessageToClient(
    @Nullable Client client,
    @Nullable String message,
    @NotNull Mailer mailer
) {
    if (client == null || message == null) return;

    PersonalInfo personalInfo = client.getPersonalInfo();
    if (personalInfo == null) return;

    String email = personalInfo.getEmail();
    if (email == null) return;

    mailer.sendMessage(email, message);
}
可以在Kotlin中重写为

val email = client?.personalInfo?.email
if (email != null && message != null) {
    mailer.sendMessage(email, message)
}

您不必在elvis运算符的右侧设置null,elvis运算符用于处理不可为null的情况

val info:EuiccInfo? = msg?.euiccInfo
val info
-定义为可空,因此如果msg为空(
msg?
意味着msg也可以为空,如果msg为空,它将无法访问
。euiccInfo
)信息将为空

让我们假设信息定义为不可为空的val

val info:EuiccInfo = msg?.euiccInfo
编译器将不允许您设置info null值,因为msg可为空, 所以你必须处理非空的情况

val info: EuiccInfo = msg?.euiccInfo ?: someDefaultNonNullValue (EuiccInfo())

使用Elvis运算符处理null大小写是不必要的(也是毫无意义的),因为如果msg为null或
msg?.euiccInfo
为null,它将被设置为null。

这可能是编译器将语法糖重写为基础运算符或方法调用。我不确定如何跟踪它们的原始实现,我只是想知道一些开明的灵魂是否能为我指明正确的方向。我在底部的问题中提到了一个注意事项,为什么我把
?:null
作为
示例
好的,谢谢,也许我没有注意到,或者你在我回答后更新了这个问题。