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编程”中已明确指出,该列表包含同类对象。
像列表一样,元组是不可变的,但是与列表不同,元组可以包含 不同类型的元素。而列表可能是List [Int]或 List [String],元组可以同时包含一个整数和一个字符串 在同一时间。
我认为在运行时,由于类型擦除,我们会看到相同的类型。如果是这样,那么使用cons运算符生成的列表/集合的正确类型是什么?
答案 0 :(得分:3)
您可以签出::
(cons)方法的签名:
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
这意味着,只要B
是B
(List元素的当前类型)的超类型,您就可以添加任何A
,并且结果列表将所有类型的元素都键入为B
。因此,Scala将选择最常见的超类型。在这种情况下,它将是Any
,这是Scala的根类型(类似于Java中的Object
)。如果您有一个更具体的普通超类型,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)
答案 1 :(得分:2)
Scala具有一种称为“子类型化”的东西。列表的元素类型将是所有单个元素类型的通用超类型。
在第一种情况下,推断的类型为List[Int]
,在第二种情况下为List[Any]
。 Int
和String
都是List[Any]
的元素是完全合法的,因为它们都是Any
的子类型(实际上,每个 type是Any
的子类型,因为Any
是 top类型)。
换句话说:第二个示例中的所有元素都是类型。它们都是Any
类型。