Scala-由cons运算符创建的集合类型

时间:2018-06-30 14:22:48

标签: scala

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运算符生成的列表/集合的正确类型是什么?

2 个答案:

答案 0 :(得分:3)

您可以签出::(cons)方法的签名:

def ::[B >: A] (x: B): List[B] =
  new scala.collection.immutable.::(x, this)

这意味着,只要BB(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]IntString都是List[Any]的元素是完全合法的,因为它们都是Any的子类型(实际上,每个 type是Any的子类型,因为Any top类型)。

换句话说:第二个示例中的所有元素都是类型。它们都是Any类型。