scala – 派生类作为类构造函数参数
[以下编辑]
我有一个类层次结构,现在大致如下: sealed trait Foo { def method: Any } case class Bar extends Foo { def method: Array[String] = // implementation } case class Baz extends Foo { def method: Map[String,Array[String]] = // implementation } 我给抽象方法一个返回类型Any,因为case类的返回类型必然不同,但它们有着相似的目的.出于这个原因,我想保持它的特性来模拟这种常见行为,这是我发现编译它的唯一方法.我意识到这违背了Scala类型系统的精神,所以我问下面的第一个问题. 然后,另一个类期望Foo的子类作为构造函数参数,我不知道如何表示这个,除了以下内容: class Qux(foo: Foo) { val m = foo.method ... ... } 后来在类Qux中有一些方法期望val m是与Foo的特定子类(Bar或Baz)对应的类型,但是我得到的编译错误就像 ... type mismatch; [error] found : Any [error] required: Array[String] 所以我有几个问题: >我对Scala足够熟悉,认为这是表达我的特定问题的正确方法,但不熟悉它以了解如何解决它.做我正在做的事情的正确方法是什么? 编辑:采用@marios建议的方法(使用抽象类型成员)似乎是朝着正确方向迈出的一步,但现在突然出现类型不匹配.在Qux类中,我现在有 class Qux[X <: Foo](sc: SparkContext,val foo: X) { val m: foo.A = foo.method def process(rows: DataFrame) = foo match { case Bar(sc,_) => BarProcessor(sc,m).doStuff(rows) case Baz(sc,_) => BazProcessor(sc,m.keys).doStuff(rows,m.values) } } 其中BarProcessor例如使用Array [String]进行实例化,而BazProcessor需要Baz方法返回的值中的键值对才能完成.但是,我现在得到的错误就像 [error] Qux.scala:4: type mismatch; [error] found : Qux.this.foo.A [error] required: Array[String] [error] case Bar(sc,m).doStuff(rows) [error] ^ 当我尝试在m上调用特定于Map的方法时,类似的错误会出现,当foo是Baz时(沿着值键的行不是Qux.this.foo.A的成员等).我知道m不是一个真正的Array [String] – 它是A类型的.但是有没有办法告诉Scala将其“翻译”成所需的类型? 解决方法
访问ADT中各个类型的更简单方法是使用抽象类型成员而不是泛型类型参数.
sealed trait Foo { type A def method: A } case object Bar extends Foo { type A = Array[String] def method: A = Array.empty[String] } case object Baz extends Foo { type A = Map[String,Array[String]] def method: A = Map.empty[String,Array[String]] } case class Qux[X <: Foo](foo: X) { def m: X#A = foo.method // You can then pattern match on m def f = m match { case a: Baz.A => a.size // Use Baz#A if Baz is a class and not an object case b: Bar.A => b.size // Use Bar#A if Bar is a class and not an object } } 使用它(看看返回类型) @ Qux(Baz).m res6: Map[String,Array[String]] = Map() @ Qux(Bar).m res7: Array[String] = Array() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |