Scala 的任何列表和扩展 Any 的列表。有什么区别?
Scala list of any and list of something extending Any. What is a difference?
谁能解释一下两者之间的区别:
Seq[Any]
和 Seq[_ <: Any]
?
在我看来,我可以把所有东西都放在这两种情况下,因为一切都扩展了 Any
.
这里没有区别,因为 Seq
is covariant。所以:
Seq[Any]
是 Seq[_ <: Any]
的子类型,因为 _
可能是 Any
;
Seq[_ <: Any]
是 Seq[Any]
的子类型,因为无论你输入什么而不是 _
,你都会得到 Seq[Any]
.[= 的子类型42=]
如果您将 Seq
替换为某些不变的 F
(例如 Set
),则 Set[Any]
是 Set[_ <: Any]
的子类型,但反之则不然。 Set[_ <: Any]
是 Set[Any]
、Set[String]
、Set[Int]
等的公共超类型
更详细:
Set[_ <: Any]
是 shorthand for Set[T] forSome { T <: Any }
.
Set[T] forSome { T <: Any }
是满足 T <: Any
类型 T
的所有 Set[T]
的超类型。规范says
The set of values denoted by the existential type T forSome {Q}
is the union of the set of values of all its type instances.
但这是一回事。
所以代码像
val set1: Set[String] = ???
val set2: Set[_ <: Any] = set1
会编译(试一试!)。如果您将 String
替换为任何其他类型(_ <: ...
不是一种类型),它仍然会。但是
val set1: Set[String] = ???
val set2: Set[Any] = set1
不会。
我将在 @AlexeyRomanov 的回答中添加 Scala 规范中特定位置的引用:
3.2.12 Existential Types
Simplification Rules
4.An existential type forSome { }
where </code> contains a clause type <code>[tps]>:<:
is equivalent to the type ′ forSome { }
where ′
results from </code> by replacing every <em>covariant</em>
occurrence of <code>
in </code> by <code>
and by replacing every
contravariant occurrence of
in </code> by <code>
.
https://scala-lang.org/files/archive/spec/2.13/03-types.html#simplification-rules
Seq[_ <: Any]
是Seq[T] forSome { type T <: Any}
,T
出现在Seq[T]
是协变的,因为Seq
是协变的,所以Seq[T] forSome { type T <: Any} =:= Seq[Any] forSome { type T <: Any} =:= Seq[Any]
(最后一步也使用简化规则 #2).
谁能解释一下两者之间的区别:
Seq[Any]
和 Seq[_ <: Any]
?
在我看来,我可以把所有东西都放在这两种情况下,因为一切都扩展了 Any
.
这里没有区别,因为 Seq
is covariant。所以:
Seq[Any]
是Seq[_ <: Any]
的子类型,因为_
可能是Any
;Seq[_ <: Any]
是Seq[Any]
的子类型,因为无论你输入什么而不是_
,你都会得到Seq[Any]
.[= 的子类型42=]
如果您将 Seq
替换为某些不变的 F
(例如 Set
),则 Set[Any]
是 Set[_ <: Any]
的子类型,但反之则不然。 Set[_ <: Any]
是 Set[Any]
、Set[String]
、Set[Int]
等的公共超类型
更详细:
Set[_ <: Any]
是 shorthand forSet[T] forSome { T <: Any }
.Set[T] forSome { T <: Any }
是满足T <: Any
类型T
的所有Set[T]
的超类型。规范saysThe set of values denoted by the existential type
T forSome {Q}
is the union of the set of values of all its type instances.但这是一回事。
所以代码像
val set1: Set[String] = ???
val set2: Set[_ <: Any] = set1
会编译(试一试!)。如果您将 String
替换为任何其他类型(_ <: ...
不是一种类型),它仍然会。但是
val set1: Set[String] = ???
val set2: Set[Any] = set1
不会。
我将在 @AlexeyRomanov 的回答中添加 Scala 规范中特定位置的引用:
3.2.12 Existential Types
Simplification Rules
4.An existential type
forSome { }
where</code> contains a clause type <code>[tps]>:<:
is equivalent to the type′ forSome { }
where′
results from</code> by replacing every <em>covariant</em> occurrence of <code>
in</code> by <code>
and by replacing every contravariant occurrence ofin
</code> by <code>
.
https://scala-lang.org/files/archive/spec/2.13/03-types.html#simplification-rules
Seq[_ <: Any]
是Seq[T] forSome { type T <: Any}
,T
出现在Seq[T]
是协变的,因为Seq
是协变的,所以Seq[T] forSome { type T <: Any} =:= Seq[Any] forSome { type T <: Any} =:= Seq[Any]
(最后一步也使用简化规则 #2).