Scala语言规范版本2.8的4.6.2节描述了重复的参数,并说:
参数部分的最后一个值参数可以以"*"为后缀,例如(...,x:T*).然后,方法中的这种重复参数的类型是序列类型scala.Seq [T].
但是,这段代码:
abstract class A { def aSeq : Seq[A] }
class B(val aSeq : A*) extends A
class C extends B { override val aSeq :Seq[A] = Seq() }
Run Code Online (Sandbox Code Playgroud)
编译时出错:
overriding value aSeq in class B of type A*; value aSeq has incompatible type
Run Code Online (Sandbox Code Playgroud)
编译器似乎表明A*是与Seq [A]不同的类型.
在这种情况下调查aSeq的实际类显示它是scala.collection.mutable.WrappedArray $ ofRef的实例,但即使以下代码也无法使用相同的消息进行编译:
class C extends B { override val aSeq = new ofRef(Array[A]()) }
Run Code Online (Sandbox Code Playgroud)
所以问题是,如何覆盖由类上重复参数定义的成员?
如果你想知道它来自何处,那就是exalaly scala.xml.Elem 在scala.xml.Node中覆盖子方法的作用.
您的问题可归纳为:
scala> class A { def aSeq(i: Int*) = 1 }
defined class A
scala> class B extends A { override def aSeq(i: Seq[Int]) = 2 }
<console>:6: error: method aSeq overrides nothing
class B extends A { override def aSeq(i: Seq[Int]) = 2 }
Run Code Online (Sandbox Code Playgroud)
方法有不同的类型.规范说(强调我的):
的类型这样的重复参数的内部的方法是,则序列类型scala.Seq [T]
由于Int*
和Seq[Int]
不在方法内,这个特定的句子不适用.
有趣的是,下面的代码显示这些方法在擦除之前有不同的类型,但之后相同:
scala> class G { def aSeq(i:Int*) = 1; def aSeq(i:Seq[Int]) = 2 }
<console>:5: error: double definition:
method aSeq:(i: Seq[Int])Int and
method aSeq:(i: Int*)Int at line 5
have same type after erasure: (i: Seq)Int
class G { def aSeq(i:Int*) = 1; def aSeq(i:Seq[Int]) = 2 }
Run Code Online (Sandbox Code Playgroud)
那么问题就变成了,为什么你的B
类可以扩展你的A
抽象类.那里的规范可能存在不一致之处.我不知道...
编辑:我重新阅读规范,我无法弄清楚是否有任何与重复参数和覆盖相关的内容.似乎没有关于重复参数的返回类型的任何内容,这是您为val aSeq
访问器方法获得的内容.
我认为Mark的答案是一种非常有效的方法.如果您无法关注它,您可以使用以下解决方法:
class C extends B {
private def aSeqHelper(a: A*) = a
override val aSeq = aSeqHelper(Seq[A](): _*)
}
Run Code Online (Sandbox Code Playgroud)
例如:
import scala.xml._
class ElemX extends Elem("pref", "label", <xml a="b"/>.attributes, TopScope) {
private def childHelper(c: Node*) = c
override val child = childHelper(<foo/><bar/>: _*) }
Run Code Online (Sandbox Code Playgroud)
然后:
scala> new ElemX
res4: ElemX = <pref:label a="b"><foo></foo><bar></bar></pref:label>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
872 次 |
最近记录: |