Kotlin 值类与内联类有何不同?

Kli*_*cou 10 kotlin

内联类和值类有什么区别?我知道,当值类被注释为时,它就是一个内联类,@JvmInline value class但这仅适用于针对 JVM 的情况。那么在其他平台上,所有值类都是隐式内联类吗?@JvmInline到底什么是非内联值类,不在JVM 上定义值类有什么用?

Jof*_*rey 10

如果想更详细的了解,可以看一下对应的KEEP

内联类和值类有什么区别?

您可以将值类视为开发人员更一般的声明,而“内联”更多的是如何编译的实现细节。

当您声明 a 时value class,您实际上放弃了此类实例的标识。这意味着您无法区分该类的相同引用和相等值。这就是此声明中遵循其他限制的主要原因(例如没有var属性或===运算符)。

一个需要记住的好例子是Int。如果它们的定义如下:和 ,则无法区分 x和。它们在各方面都是平等的,因为在这里谈论引用是没有意义的。这就是为什么在像这样的原始类(以及值类)上被禁止的原因。yval x = 42val y = 41 + 1===

放弃身份为内联或其他优化打开了大门,但值类不必这种方式实现。事实上,即使实验inline类并不总是“内联”,在某些情况下它们也必须像这样装箱Int(例如,当用作泛型类型参数或用作父类型时)。

那么在其他平台上,所有值类都是隐式内联类吗?

从上面的解释中,可能会更清楚地看到内联只是实现此类的一种可能的方式。实际上,对于开发人员来说,编译器在不同平台上在幕后使用什么并不重要(这只是优化)。但是,是的,在 Native 和 JS 上,编译器更容易内联内容。请查看KEEP 的这一部分,了解有关平台细节的更多信息。

到底什么是非内联值类,在 JVM 上定义不带 @JvmInline 的值类有什么用?

目前不支持这些(您必须@JvmInline在 Kotlin 1.5 中指定)。1.5中只使用了“内联”实现策略。然而,Kotlin 团队希望以后能够采用其他潜在的实现策略,例如利用Project Valhalla的新类型。为了以向后兼容的方式做到这一点,现在拥有此注释并允许以后不再指定它会有所帮助。来自 KEEP:

@JvmInline 注释明确表明 JVM 中正在发生此类的特殊情况,并且它使我们能够通过使用 Valhalla 项目的功能来编译它们,从而在未来的 Valhalla JVM 中支持非注释值类。