使用 a.tail:_ * 即可 但不是 a.tail:A * 为什么?
提前感谢您的帮助
case object Nil extends List[Nothing]
case class Cons[+A](h: A, t: List[A]) extends List[A]
trait List[+A]
object List {
def apply[A](a: A*): List[A] = {
if (a.isEmpty) Nil
else Cons(a.head, apply(a.tail: _*))
//else Cons(a.head, apply(a.tail: A*))
}
}
答案 0 :(得分:2)
如您所知,当您向方法体中的参数类型添加星形时(在这种情况下为apply),您告诉Scala接受任意数量的A.这与不与说“采取A序列”相同;如果你想要,你可以写a: Seq[A]
。据我所知,使用Seq[A]
可以达到与A*
相同的效果,但是您需要一些样板来处理空序列的情况,以及遍历序列的指令。因此,它不太方便。
现在,为什么你不能使用A*
?好吧,因为你没有为a.tail
声明一个类型;它已经有一个类型,那个类型是List[A]
。相反,因为你需要将它作为参数传递给apply
,它接受可变数量的参数A*
(一个Varargs参数),你需要告诉Scala编译器序列{{1 (在这种情况下为List序列)不能作为序列传递给方法:这将是单个参数,而不是变量编号,因此不正确。相反,a.tail
用于将序列转换为可以作为可变数量的参数传递的东西,“一次一个”,实质上。
因此,: _*
签名改变现有序列如何处理,但该序列已经有一个类型,它只是一个与之不兼容的类型没有某种转换的Varargs参数。 : _*
提供了转化。请注意您只需要使用它,因为您要将: _*
传递给接受可变数量参数的方法a.tail
。如果您没有将其传递给Varargs方法,则无需添加apply
。