了解 Kotlin 类型系统,`{Comparable<{ Double & Int }> & Number}` 是什么意思以及如何使用它
Understanding Kotlin Type system, What is meant by `{Comparable<{ Double & Int }> & Number}` and how to work with that
例如:
var a = true
val test = if (a) -1 else -3.2
我期待 test
的类型应该是类型层次结构的最接近的交集,即 Int 和 Double 是 Number
。
但是看IDE,好像是{Comparable<{ Double & Int }> & Number}
的类型。
奇怪的是,我不能那样指定它(因为 {} 是为创建 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 接口时,您如何使用它的函数?
问题 1 的答案是编译器正在尽最大努力推断类型,发明新的约束来描述它。
问题 2 的答案是不能。
问题 3 的答案是不能,因为 Int
与 Double
不可比,反之亦然。因此 Comparable
中的 none 方法实际上是可用的,但该值肯定实现了 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
&
这里表示交集类型(Kotlin 语言本身不支持,但编译器在内部使用它们)。你可以看到它在(不完整)specification.
中提到
Intersection types are special non-denotable types used to express the fact that a value belongs to all of several types at the same time.
"Non-denotable" 恰恰意味着您不能指定该类型。我不确定,但我认为类型中额外的 {
}
应该准确地表明这一点。
特别是,Comparable<Double & Int>
意味着您只能将 test
与 Double
和 Int
进行比较,但是没有这样的值。编译器可能会将其简化为 Comparable<Nothing>
.
the most closest intersection of the type-hierarchy i.e. for Int
and Double
is Number
.
是最小上界,更接近于并集,而不是交集。规范实际上称它为 "union types",但这不是该术语的正常用法。
这个最小上限不是 Number
因为它 也 取 Comparable
接口的最小上限Comparable<Double & Int>
因为 Comparable
是逆变的:
lub(Int, Double) =
Number & lub(Comparable<Int>, Comparable<Double>) =
Number & Comparable<Int & Double>
此计算在 type decaying 下进行了描述:
All union types are subject to type decaying, when they are converted to a specific intersection type, representable within Kotlin type system.
例如:
var a = true
val test = if (a) -1 else -3.2
我期待 test
的类型应该是类型层次结构的最接近的交集,即 Int 和 Double 是 Number
。
但是看IDE,好像是{Comparable<{ Double & Int }> & Number}
的类型。
奇怪的是,我不能那样指定它(因为 {} 是为创建 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 接口时,您如何使用它的函数?
问题 1 的答案是编译器正在尽最大努力推断类型,发明新的约束来描述它。
问题 2 的答案是不能。
问题 3 的答案是不能,因为 Int
与 Double
不可比,反之亦然。因此 Comparable
中的 none 方法实际上是可用的,但该值肯定实现了 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
&
这里表示交集类型(Kotlin 语言本身不支持,但编译器在内部使用它们)。你可以看到它在(不完整)specification.
Intersection types are special non-denotable types used to express the fact that a value belongs to all of several types at the same time.
"Non-denotable" 恰恰意味着您不能指定该类型。我不确定,但我认为类型中额外的 {
}
应该准确地表明这一点。
特别是,Comparable<Double & Int>
意味着您只能将 test
与 Double
和 Int
进行比较,但是没有这样的值。编译器可能会将其简化为 Comparable<Nothing>
.
the most closest intersection of the type-hierarchy i.e. for
Int
andDouble
isNumber
.
是最小上界,更接近于并集,而不是交集。规范实际上称它为 "union types",但这不是该术语的正常用法。
这个最小上限不是
Number
因为它 也 取Comparable
接口的最小上限Comparable<Double & Int>
因为Comparable
是逆变的:lub(Int, Double) = Number & lub(Comparable<Int>, Comparable<Double>) = Number & Comparable<Int & Double>
此计算在 type decaying 下进行了描述:
All union types are subject to type decaying, when they are converted to a specific intersection type, representable within Kotlin type system.