如何从Scala API for List解释:::

时间:2012-10-15 21:44:45

标签: scala

我正在尝试使用:::中的List方法(这是一个运算符方法吗?)。好的,我知道在REPL中输入两个列表并看到发生了什么之后它现在正在做什么。但是,:::方法的API定义很难阅读和理解。我只是通过阅读它“返回”的内容来“得到它”。

def :::[B >: A](prefix: List[B]): List[B]
    Adds the elements of a given list in front of this list.
    prefix  The list elements to prepend.
    returns list resulting from the concatenation of the given list prefix and this list.
    Example:  List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4)

特别是这部分是什么意思:[B >: A](prefix: List[B])。我的意思是我能够通过阅读方法返回并使用它来播放该方法返回的内容。对于未来,我希望能够阅读API以获得不同的方法并尝试理解所有内容。这就是我提出这个问题的原因。

3 个答案:

答案 0 :(得分:4)

[B >: A]表示该方法是通用的,并且采用一个名为B的类型参数,该参数必须是A的超类型。 (prefix : List[B])表示它需要一个名为prefix List[B]的实际参数。

答案 1 :(得分:2)

如果不是因为子类型会写为def :::(prefix: List[A]): List[A],那么[B >: A]只会让List[Animal]加上List[Cat]的前缀,变得更大List[Animal]

答案 2 :(得分:1)

这两个答案都是正确的。您只需记住A是当前列表的类型参数,而B是您要提供给:::的列表的类型参数

如果您还不自信,可以尝试自己定义的List

  class MyList[+A]{
    def :::[B >: A](prefix: MyList[B]): MyList[B] = new MyList[B]()
  }

  class Animal
  class Dog extends Animal
  class Pig extends Animal
  class Rock 

现在你可以在REPL中进行测试:

scala>  new MyList[Dog]
res0: Test.AkkaTest.MyList[Test.AkkaTest.Dog] = Test.AkkaTest$MyList@190a0d51

scala>  new MyList[Pig]
res1: Test.AkkaTest.MyList[Test.AkkaTest.Pig] = Test.AkkaTest$MyList@1db5d2b2

scala>  res0:::res1
res2: Test.AkkaTest.MyList[Test.AkkaTest.Animal] = Test.AkkaTest$MyList@25927275

scala>  new MyList[Rock]
res3: Test.AkkaTest.MyList[Test.AkkaTest.Rock] = Test.AkkaTest$MyList@49f85a86

scala>  res3:::res0
res4: Test.AkkaTest.MyList[ScalaObject] = Test.AkkaTest$MyList@42130c2

scala>  res0:::res3
res5: Test.AkkaTest.MyList[ScalaObject] = Test.AkkaTest$MyList@6f24d504

所以你知道应该理解:::连接两个列表并创建一个列表,其泛型类型是第一个共同的祖先。这是因为类型列表是协变的,所以例如你可能认为,在res3和res0的情况下,编译器执行以下操作:

  • A是Rock B是Dog,B不是A的父类,也许我应该抛出编译错误?
  • 但由于MyList是协变的,MyList [Dog]是MyList [ScalaObject]的子类。
  • 酷,ScalaObject是Rock的父类,所以我将创建一个ScalaObject列表