Kotlin:在什么情况下会发生隐式转换? [英] Kotlin: At which situations does implicit conversion happen?

查看:32
本文介绍了Kotlin:在什么情况下会发生隐式转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

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

然后当我阅读部分

<块引用>

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

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

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

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

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

解决方案

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

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

<块引用>

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

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

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

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

<块引用>

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

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

I am a beginner in Kotlin. I'm most familiar with Python, and I just read through the basic Java Tutorial https://docs.oracle.com/javase/tutorial/java/index.html before jumping into Kotlin.

A question came up in my mind while reading this section of the documentation of Kotlin

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

What I have understood from above section of the documentation is:

  • For assignments =, implicit type conversion happens. If the lefthand side's type is a supertype or same type of righthand side's type the code would compile. Otherwise it's a compile error. In case of Int and Long, they are both subtypes of Number but neither of them subtypes of each other, so the implicit conversion would not work. Therefore we need to use methods like .toLong() or .toInt() to explicitly convert them.

Then when I read the part

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

I started wondering if implicit type conversion would be taking place in this situation.

The documentation says this has to do with the operator overloading. How is this operator overloading implemented under the hood? I tried to find the source code at Github https://github.com/JetBrains/kotlin/blob/master/core/builtins/native/kotlin/Primitives.kt , but here the functions are only declared but not implemented. Where can I find the implementations?

It seems that operation overloading does not actually perform type conversion. Do we just implementing all possible functions with same name but different parameter type signatures, so that the type is inferred, then the function with the matching signature is selected?

And the general question: In Kotlin, exactly at which situations does implicit conversion happen?

解决方案

For assignments =, implicit type conversion happens. If the lefthand side's type is a supertype or same type of righthand side's type the code would compile.

Assignments aren't special in this. More generally, if the expected type of an expression is a supertype or the same as actual type, the code compiles; it's just that the expected type for the right-hand side of an assignment is the left-hand side's type. I wouldn't say there is an implicit conversion inserted, but I don't think anything breaks if you see it that way.

Do we just implementing all possible functions with same name but different parameter type signatures, so that the type is inferred, then the function with the matching signature is selected?

Yes, exactly (for this case). If you want to support primitive types, you need to provide overloads for all of them.

So 1L + 3 is just a method call so far as the parsing and type-checking is concerned (`Long.plus(Int): Long specifically), no implicit conversion is involved. But these methods are built into the compiler to handle specially which is why you don't see an implementation.

It becomes two bytecode instructions i2l ("convert an int into a long") and ladd ("add two longs"), but that's not something you should probably care about yet, or for a long time.

And the general question: In Kotlin, exactly at which situations does implicit conversion happen?

Smart casts are the closest Kotlin has to implicit conversions but they are sufficiently different from i.c.s in other languages that I wouldn't use the name. So I'd say never.

这篇关于Kotlin:在什么情况下会发生隐式转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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