了解Kotlin类型系统,{{Comparable&Number}`的含义以及如何使用它

问题描述 投票:0回答:2

例如:

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

我曾期望test的类型应该是类型层次结构中最接近的交集,即Int和Double为Number

但是在IDE中,它似乎具有{Comparable<{ Double & Int }> & Number}的类型。

IDE Snapshot

而且很奇怪,我不能这样指定(由于{}是保留用于创建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)

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

  • 该类型如何一起工作,即一个变量如何一次容纳两种类型?
  • 一个人怎么可以明确指定这种类型?
  • 当测试实现后,如何使用Comparable接口中的功能?
kotlin types interface multiple-inheritance
2个回答
0
投票

问题1的答案是,编译器正在尽最大努力来推断类型,发明了新的约束条件来描述它。

问题2的答案是你不能。

问题3的答案是您不能,因为IntDouble不具有可比性,反之亦然。因此Comparable中的所有方法实际上都不可用,但是该值肯定针对something实现了Comparable。这对Comparable没用,但可能对另一个接口有用。例如,假设:

interface ZeroAndComparable<T> {
  fun compareTo(t: T): Int
  fun zero(): T
}

val foo : ZeroAndComparable<Int> = someZeroAndComparableInt()
val bar : ZeroAndComparable<Double> = someZeroAndComparableDouble()
val foobar = if (a) foo else bar
val zero : Any = foobar.zero() // should work
foobar.compareTo(something) // cannot work

0
投票

&在这里表示交集类型(Kotlin语言本身不支持,但是编译器在内部使用它们)。您可以在[不完整] specification中看到它。

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

“ Non-denotable”表示您无法指定该类型。我不确定,但我认为类型中多余的{ }应该恰好表明了这一点。

特别是Comparable<Double & Int>表示您只能将testboth DoubleInt进行比较,但没有此类值。

类型层次结构中最接近的交点,即IntDouble的交点是Number

  1. 这是最小的上限,它更接近联合,而不是交集。

  2. 此最小上限不是Number,因为它[[also占据了Comparable接口的最小上限,因为Comparable<Double & Int>是互变的:

    Comparable
此计算实际上也在lub(Int, Double) = 
Number & lub(Comparable<Int>, Comparable<Double>) =
Number & Comparable<Int & Double>
下进行了描述:

[所有并集类型在转换为可在Kotlin类型系统中表示的特定相交类型时,都会经历类型衰减。

尽管规范对“联合类型”的使用是

不是标准之一。

© www.soinside.com 2019 - 2024. All rights reserved.