2017-03-28 78 views
2

所以我一直在研究我的项目中的重构,将Vector的代码转换为Array的。原因是我的应用程序需要非常高效,并且使用Array的while-iterations比在Vector上的理解和迭代要快得多。 (请参阅this blog post for details斯卡拉阵列泛型vs向量泛型

但是我遇到了一个问题,我似乎无法轻松找到答案。我调整了我的代码来隐藏实现细节,并简化为需要强调此问题的代码。

下面的类结构,采用Vector时,编译完全罚款:

sealed abstract class BaseClass {  
    def element: Int 
} 

sealed abstract class TypeA extends BaseClass { 
    def element = 2 
    def children: Vector[BaseClass] 
} 

case class TypeB(element: Int = 2) extends BaseClass 
case class TypeAA(children: Vector[TypeA]) extends TypeA 
case class TypeAB(children: Vector[TypeB]) extends TypeA 

现在,使用Vector切换到使用Array时,不再编译:

sealed abstract class BaseClass { 
    def element: Int 
} 

sealed abstract class TypeA extends BaseClass { 
    def element = 2 
    def children: Array[BaseClass] 
} 

case class TypeB(element: Int = 2) extends BaseClass 
case class TypeAA(children: Array[TypeA]) extends TypeA 
case class TypeAB(children: Array[TypeB]) extends TypeA 

我得到的对于TypeAA和TypeAB类错误:overriding method children in class TypeA of type => Array[BaseClass]; value children has incompatible type

我有一种感觉,我需要做一个隐式转换的地方,但我相对较新的斯卡拉(只有几个月),我不确定如何使用它。

对不起,如果这已被问到别处,我无法找到正确的搜索条件,我遇到的问题。

+1

的问题是' Array'在Scala中不变,而Vector是协变的。这意味着'Vector [TypeA]'是Vector [BaseClass]的子类型,但是Array [TypeA]不是Array [BaseClass]的子类型。 –

回答

3

我认为你需要使用_ <: BaseClass而不是使用泛型类型本身:

sealed abstract class TypeA extends BaseClass { 
    def element = 2 
    def children: Array[_ <: BaseClass] 
} 

这是因为在Array泛型类型参数是不变的,而在Vector是协变:

final class Array[T] 
final class Vector[+A] 

希望能帮到你。

+0

不幸的是,没有工作:/ –

+0

是的,对不起,我急于解决这个问题。问题在于泛型类型 - 您应该使用上限来实现这一点。 –

+0

是的,您的修改按预期工作,非常感谢! –

1

这来自于一个事实Vector[+A]在其类型参数协AArray[A]不是在A

意思不变,您可以使用F-Bounded Polymorphism解决这个事实:

sealed abstract class TypeA[A :< Type[A]] extends BaseClass { 
    def children: Array[A] 
} 
case class TypeAA(children: Array[TypeA]) extends TypeA[TypeA] 
case class TypeAB(children: Array[TypeB]) extends TypeA[TypeB] 
+0

谢谢!我试图通过注册,但由于帐户限制而无法使用。我第一次接受安德烈的回答。感谢您的帮助! –