首页 > 解决方案 > 了解 Kotlin 类型系统,`{Comparable<{ Double & Int }> & Number}` 的含义以及如何使用它

问题描述

例如:

var a = true
val test = if (a) -1 else -3.2

我期待的 Typetest应该是类型层次结构的最接近的交集,即 Int 和 Double 是Number

但是看IDE,好像有一种{Comparable<{ Double & Int }> & Number}.

IDE 快照

奇怪的是,我不能这样指定它(因为 {} 是为创建 lambda 保留的),我只能将它设置为Number.

另一个奇怪的事情是,如果我从 Comparable 接口尝试一些函数,它会引发一些错误:

// Warning at value 2
// The integer literal does not conform to the expected type {Double & Int}
test.compareTo(2)

3.compareTo(-1.1) // possible
2.3.compareTo(100) // possible

// But why not this is possible, while it has inferred type of Comparable?
test.compareTo(2)

有人可以帮助理解这里的概念吗?还有几个问题:

标签: kotlintypesinterfacemultiple-inheritance

解决方案


&这里的意思是交集类型(Kotlin 语言本身不支持,但编译器在内部使用它们)。您可以在(不完整的)规范中看到它。

交集类型是特殊的不可表示类型,用于表示一个值同时属于所有几种类型的事实。

“不可表示”意味着您不能指定该类型。我不确定,但我认为额外{ }的类型应该准确地表明这一点。

特别是,Comparable<Double & Int>意味着您只能与同时为和test的东西进行比较,但没有这样的值。编译器可能会将其简化为. DoubleIntComparable<Nothing>

类型层次结构的最接近的交集,即 forIntDoubleis Number

  1. 它是最小的上限,更接近联合,而不是交集。规范实际上将其称为“联合类型”,但这不是该术语的正常用法。

  2. 这个最小上限不是Number因为它Comparable需要接口的最小上限,Comparable<Double & Int>因为它Comparable是逆变的:

    lub(Int, Double) = 
    Number & lub(Comparable<Int>, Comparable<Double>) =
    Number & Comparable<Int & Double>
    

此计算在类型衰减下描述:

所有联合类型都受到类型衰减的影响,当它们转换为特定的交集类型时,可在 Kotlin 类型系统中表示。


推荐阅读