scala应用方法类型错误的原因(可变函数)

scala应用方法类型错误的原因(可变函数),scala,Scala,使用a.tail:*可以 但不是尾巴:为什么 提前谢谢你的帮助 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: _*

使用a.tail:*可以
但不是尾巴:为什么

提前谢谢你的帮助

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*))
  }
}

正如您所知,当您向方法体中的参数类型添加星号时(在本例中为apply),您会告诉Scala接受任意数量的a。这与说“取a的序列”不同;如果你想这样,你可以写
a:Seq[a]
。据我所知,使用
Seq[A]
可以达到与
A*
相同的效果,但您需要一些样板来处理空序列的情况,并根据指令遍历序列。因此,它不太方便

现在,为什么不能使用
A*
?好吧,因为您没有为
a.tail
声明类型;它已经有一个类型,该类型是
List[a]
。相反,由于您需要将其作为参数传递给
apply
,后者接受数量可变的参数,
a*
(一个Varargs参数),因此您需要告诉Scala编译器序列
a.tail
(在本例中是一个列表序列)不能作为序列传递给方法:这将是一个单参数,不是可变数字,因此不正确。相反,
:*
将序列调整为可以作为可变数量的参数传递的内容,本质上是“一次一个”


因此,
:*
签名改变了现有序列的处理方式,但该序列已经有了一个类型,它只是一个与Varargs参数不兼容的类型,没有某种转换<代码>:*提供该转换。请注意,您只需要使用它,因为您要将
a.tail
传递到一个方法
apply
,该方法接受可变数量的参数。如果不将其传递给Varargs方法,则不需要添加
:*

,但我的IDEIntellij显示'a'是
Seq[a]
,'a.tail'也是
Seq[a]
而不是
List[a]
,'a'来自
a*
类型。如果
A*
等于type
Seq[A]
,那么为什么第二个
apply
需要转换
不仅仅是
Seq[A]
A*
。。。或者
A*⊂ 序号[A]&A*≠ Seq[A]
?Seq[A]是列表的超类型。抱歉,我忘了您使用的是自定义列表定义,然后。LinearSeq是Seq的又一个亚型。查看它的线性子类型,您将看到List、Stream和一系列其他集合。其思想是,编译器将能够检测您是否正在构造线性序列,这就是您的列表,并将其视为线性序列。换句话说,正如Seq[A]。
A*
不等于
Seq[A]
,这就是重点
Seq[A]
是一个参数,一个输入,
A*
可以接受0个或多个不同的输入。
Seq[A]
可以转换为
n
参数,其中
n=Seq[A].length
。要告诉编译器执行此操作,请使用
:*
键入“operator”。这有用吗?另外,请查看Peter Neyen的评论以获得进一步的澄清。非常感谢您,现在我明白了:)非常清楚。而且。。。关于接受;不幸的是,我的第11点低于15点:第15点是你可以接受答案的点;我很抱歉,当我说到点子上的时候,我会提出你的详细回答