首页 > 解决方案 > Kotlin:在哪些情况下会发生隐式转换?

问题描述

我是 Kotlin 的初学者。我最熟悉 Python,在进入 Kotlin 之前,我刚刚通读了基本的 Java 教程https://docs.oracle.com/javase/tutorial/java/index.html 。

在阅读 Kotlin 文档的这一部分时,我想到了一个问题

https://kotlinlang.org/docs/reference/basic-types.html#explicit-conversions

我从文档的上述部分了解到的是:

然后当我读到这部分

val l = 1L + 3 // Long + Int => Long

我开始想知道在这种情况下是否会发生隐式类型转换。

文档说这与运算符重载有关。这个运算符重载是如何在后台实现的?我试图在 Github https://github.com/JetBrains/kotlin/blob/master/core/builtins/native/kotlin/Primitives.kt上找到源代码,但这里只声明了函数但没有实现。我在哪里可以找到实现?

似乎操作重载实际上并没有执行类型转换。我们是否只是实现了所有可能的具有相同名称但参数类型签名不同的函数,以便推断类型,然后选择具有匹配签名的函数?

还有一个普遍的问题:在 Kotlin 中,隐式转换究竟在哪些情况下发生?

标签: kotlintype-conversion

解决方案


对于赋值 =,会发生隐式类型转换。如果左侧的类型是超类型或右侧类型的相同类型,则代码将编译。

作业在这方面并不特别。更一般地,如果表达式的预期类型是超类型或与实际类型相同,则代码编译;只是赋值右侧的预期类型是左侧的类型。我不会说插入了隐式转换,但是如果您这样看,我认为不会有任何问题。

我们是否只是实现了所有可能的具有相同名称但参数类型签名不同的函数,以便推断类型,然后选择具有匹配签名的函数?

是的,完全正确(对于这种情况)。如果要支持原始类型,则需要为所有这些类型提供重载。

就解析和类型检查而言,这1L + 3只是一个方法调用(特别是`Long.plus(Int): Long),不涉及隐式转换。但是这些方法内置在编译器中以进行特殊处理,这就是您看不到实现的原因。

它变成了两个字节码指令i2l(“将一个 int 转换为一个 long”)和ladd(“添加两个 long”),但这不是你应该关心的事情,或者很长时间都不应该关心。

还有一个普遍的问题:在 Kotlin 中,隐式转换究竟在哪些情况下发生?

智能转换是 Kotlin 最接近隐式转换的方法,但它们与其他语言中的 ics 有很大不同,因此我不会使用这个名称。所以我会说永远不会。


推荐阅读