简体   繁体   中英

Can't call an overloaded constructor in Scala

My code looks like this:

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

I get this syntax error:

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])

I don't see why the second alternative isn't used. Is there a distinction between "Any" and "_" that's tripping me up here?

As Kim already said, you need to make your array covariant in his element type, because Scala's Arras are not covariant like Java's/C#'s.

This code will make it work for instance:

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

This just tells the compiler that T should be covariant (this is similar to Java's ? extends T or C#'s out T ).

If you need more control about what types are allowed and which not, you can also use:

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

This will tell the compiler that T can be any subtype of Any (which can be changed from Any to the class you require, like CharSequence in your example).

Both cases work the same in this scenario:

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

Edit: If the class in question is not in your control, declare the type you want explicitly like this:

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

Update

This is the source code in question:

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

I wonder if someone forgot to remove the workaround, because #2005 is fixed since May 2011...

Array[Array[String]] is not a subtype of Array[Array[Any]] because Array's type parameter is not covariant. You should read up on co-, contra- and invariance . This should fix it:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM