2015-03-19 64 views
0

我的代码很简单:为什么Scala编译器认为存在多态类型错误?

class MyClass { 
    var foo: IndexedSeq[MyClass] = IndexedSeq() 
    def bar(newValues: MyClass*) = foo = newValues.toArray 
} 

类包含一个变量和方法。变量fooMyClass对象的IndexSeq。它还包含一个方法bar,它将MyClass对象的参数设置为Seq。由于Seq[T]不能被分配到IndexSeq[T],因为后者是前者的一个子类,我不得不打电话给toArray

有了这个代码,编译器会抱怨如下

polymorphic expression cannot be instantiated to expected type; 
found : [B >: MyClass]Array[B] 
required: IndexedSeq[MyClass] 
    def bar(newValues: MyClass*) = foo = newValues.toArray 
               ^

于是我找到了一个解决方案,这是调用toIndexSeq而不是toArray,而编译器不会再抱怨了。

即使问题没有解决,我仍然想知道为什么会出现这样的错误。

+0

[Scala隐式转换从Array \ [T \]到IndexedSeq \ [T \]]的可能重复(http://stackoverflow.com/questions/26704028/scala-implicit-conversion-from-arrayt-to-indexedseqt) – 2015-03-19 03:28:51

回答

0

如果你看看spec for Array,你会注意到它不会延伸SeqIndexedSeq。实际上,Array非常简单,只扩展了SerializableCloneable,因为它基于Java Array实现。由于ArrayArrayOps中提供了隐式转换,因此您可能习惯将其视为Seq

问题是没有从Array[B >: MyClass](这是toArray返回的内容)到IndexedSeq[MyClass]的隐式转换。如果您明确提供的toArray或使用类型归属泛型参数,这个问题就解决了,因为有一个隐式转换从Array[MyClass]Seq[MyClass]

def bar(newValues: MyClass*) = foo = newValues.toArray[MyClass] 
def bar(newValues: MyClass*) = foo = (newValues.toArray : Array[MyClass]) 

这更简单的例子可能有助于阐明:

class Foo 
Seq(new Foo).toArray : Seq[Foo] //fails 
Seq(new Foo).toArray[Foo] : Seq[Foo] //works! 
(Seq(new Foo).toList.toArray : Array[Foo]) : Seq[Foo] //also works! 
+0

'toArray'是否返回一个不同于'[this diagram]中的'Array'(http://docs.scala-lang.o RG /资源/图像/ collections.immutable.png)? – 2015-03-19 04:07:03

+1

不,我猜那些带虚线的箭头意味着“数组”和“字符串”可以隐式转换为“IndexedSeq”。 – 2015-03-19 10:34:53

+0

是的 - 虚线箭头表示'Predef'中存在隐式转换,粗体线表示实例化特性的方法返回的默认类型。例如,Seq()返回一个List()(它是一个LinearSeq),而IndexedSeq返回一个Vector。 – 2015-03-19 13:03:04

相关问题