【问题标题】:Kotlin: At which situations does implicit conversion happen?Kotlin:在哪些情况下会发生隐式转换?
【发布时间】:2020-02-19 18:48:44
【问题描述】:

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

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

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

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

  • 对于赋值=,会发生隐式类型转换。如果左侧的类型是超类型或右侧类型的相同类型,则代码将编译。否则就是编译错误。对于IntLong,它们都是Number 的子类型,但它们都不是彼此的子类型,因此隐式转换不起作用。因此,我们需要使用 .toLong() 或 .toInt() 等方法来显式转换它们。

然后当我阅读该部分时

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

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

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

看来操作重载实际上并没有进行类型转换。我们是否只是实现了所有可能的同名但参数类型签名不同的函数,从而推断出类型,然后选择具有匹配签名的函数?

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

【问题讨论】:

    标签: kotlin type-conversion


    【解决方案1】:

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

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

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

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

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

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

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

    Smart casts 是 Kotlin 最接近隐式转换的方法,但它们与其他语言中的 i.c.s 有很大不同,因此我不会使用该名称。所以我会说永远不会。

    【讨论】:

    • 感谢您的回复。所以在赋值中,并不是插入了隐式转换,而只是赋值右侧的类型与左侧的类型匹配(意思是, 或其子类型)。那么如果我理解正确的话,在 Kotlin 中没有隐式类型转换之类的东西,除了数字文字的情况(例如 val a: Long = 1 其中 1 是 Int)。
    • @jazzinpark 是的,没错。
    猜你喜欢
    • 2013-06-05
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 2023-04-02
    • 2020-02-20
    相关资源
    最近更新 更多