Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't call an overloaded constructor in Scala

Tags:

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?

like image 965
David Matuszek Avatar asked Jul 18 '11 15:07

David Matuszek


People also ask

What is constructor overloading in Scala?

A scala class can contain zero or more auxiliary constructors. The auxiliary constructor in Scala is used for constructor overloading and defined as a method using this name. The auxiliary constructor must call either previously defined auxiliary constructors or primary constructors in the first line of its body.

Can Scala object have constructor?

Constructors in Scala describe special methods used to initialize objects. When an object of that class needs to be created, it calls the constructor of the class. It can be used to set initial or default values for object attributes.

What is type constructor in Scala?

You can use certain types (like Int or String ) using literals ( 1 or 2 for Int or "James" for String ). Type constructors are types that need other types to be built. List or Option won't be a fully qualified type unless you pass another type to them (i.e. List[Int] or Option[String]


1 Answers

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 ...

like image 86
soc Avatar answered Sep 26 '22 06:09

soc