无法在Scala中调用重载的构造函数

时间:2011-07-18 15:54:53

标签: scala

我的代码如下所示:

val people = Array(Array("John", "25"), Array("Mary", "22"))
val headers = Seq("Name", "Age")
val myTable = new Table(people, headers)

我收到此语法错误:

overloaded method constructor Table with alternatives:
    (rows: Int,columns: Int)scala.swing.Table 
    <and>
    (rowData: Array[Array[Any]],columnNames: Seq[_])scala.swing.Table
    cannot be applied to
    (Array [Array[java.lang.String]], Seq[java.lang.String])

我不明白为什么不使用第二种替代品。 “Any”和“_”之间是否有区别让我在这里绊倒?

2 个答案:

答案 0 :(得分:5)

正如Kim已经说过的,你需要让你的数组在他的元素类型中协变,因为Scala的Arras不像Java的/ C#那样是协变的。

此代码将使其适用于例如:

class Table[+T](rowData: Array[Array[T]],columnNames: Seq[_])

这只是告诉编译器T应该是协变的(这类似于Java的? extends T或C#的out T)。

如果您需要更多地控制允许的类型和不允许的类型,您还可以使用:

class Table[T <: Any](rowData: Array[Array[T]],columnNames: Seq[_])

这将告诉编译器T可以是Any的任何子类型(可以从Any更改为您需要的类,例如示例中的CharSequence )。

在这种情况下,两种情况都是相同的:

scala> val people = Array(Array("John", "25"), Array("Mary", "22"))
people: Array[Array[java.lang.String]] = Array(Array(John, 25), Array(Mary, 22))   

scala> val headers = Seq("Name", "Age")
headers: Seq[java.lang.String] = List(Name, Age)

scala> val myTable = new Table(people, headers)
myTable: Table[java.lang.String] = Table@350204ce

修改:如果相关课程不在您的控制范围内,请明确声明您想要的类型:

val people: Array[Array[Any]] = Array(Array("John", "25"), Array("Mary", "22"))

<强>更新

这是有问题的源代码:

// TODO: use IndexedSeq[_ <: IndexedSeq[Any]], see ticket [#2005][1]
def this(rowData: Array[Array[Any]], columnNames: Seq[_]) = {

我想知道是否有人忘记删除解决方法,因为#2005自2011年5月起已修复...

答案 1 :(得分:3)

Array[Array[String]] Array[Array[Any]]的子类型,因为Array的类型参数不是协变的。你应该阅读co-, contra- and invariance。这应该解决它:

val people = 
  Array(Array("John", "25"), Array("Mary", "22")).asInstanceOf[Array[Array[Any]]