哪些类型的集合是由cons操作符创建的?
1::2::Nil
// println((1::2::Nil).getClass)
// class scala.collection.immutable.$colon$colon
"abc"::1::2::Nil
// println(("abc"::1::2::Nil).getClass)
// class scala.collection.immutable.$colon$colon
val x:List[Int] = 1::2::Nil
// println(x.getClass)
// class scala.collection.immutable.$colon$colon
这使得列表看起来可以同时包含string和Int。但是,这在“Scala中的编程”中被特别指出,该列表包含了同构对象。
与列表一样,元组是不可变的,但与列表不同,元组可以包含不同类型的元素。虽然列表可能是ListInt或ListString,但元组可以同时包含整数和字符串。
我认为在运行时,由于类型擦除,我们会看到相同的类型。如果是这样的话,那么使用con运算符生成的列表/集合的正确类型是什么?
发布于 2018-06-30 07:14:57
您可以签出::
(cons)方法的签名:
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
这意味着,只要B
是A
(当前类型的列表元素)的超级类型,您就可以在其中添加任何元素,生成的列表中的所有元素都将被键入为B
。因此Scala将选择最常见的超级类型。在这个特殊的例子中,它将是Any
,它是Scala的根类型(类似于Object
中的Java)。如果您有一个更具体的通用超级类型,Scala将努力使用它而不是Any
。
> class Animal
> class Cat extends Animal
> class Dog extends Animal
> new Cat :: new Cat :: Nil
res3: List[Cat] = List(ammonite.$sess.cmd1$Cat@2b974137, ammonite.$sess.cmd1$Cat@71734463)
> new Dog :: res3
res4: List[Animal] = List(ammonite.$sess.cmd2$Dog@79f3f34c, ammonite.$sess.cmd1$Cat@2b974137, ammonite.$sess.cmd1$Cat@71734463)
发布于 2018-06-30 07:01:42
Scala有一个叫做"subytping“的东西。列表的元素类型将是所有单个元素类型的公共超类型。
在第一个例子中,推断的类型是List[Int]
,在第二个例子中是List[Any]
。Int
和String
都是List[Any]
的元素是完全合法的,因为两者都是Any
的子类型(实际上,每种类型都是Any
的子类型,因为Any
是顶级类型)。
换句话说,第二个例子中的所有元素都是相同类型的。它们都是Any
类型的。
https://stackoverflow.com/questions/51115784
复制