vinayawsm
vinayawsm

Reputation: 865

Scala: ArrayBuffer doesn't take parameters

I have a variable of a trait that accepts multiple datatypes {Int, Long, String, Double}.

I need to do some math operation on this variable. So I try to convert the variable to an ArrayBuffer [Any].

def toArray (x: MultiV): ArrayBuffer [Any] = {
    val a = new ArrayBuffer[Any]()
    for (i <- 0 until rows) a += x(i)   // x(i) belongs to set {Int, Long, String, Double}
    a
}

Now as I need to perform some operations on this try to convert ArrayBuffer to their individual types.

def printInd (a: ArrayBuffer [Any], b: Seq[Int]) = {
    val v = a(0) match {
        case _: Double   => a.asInstanceOf [ArrayBuffer [Double]]
        case _: Int      => a.asInstanceOf [ArrayBuffer [Int]]
        case _: Long     => a.asInstanceOf [ArrayBuffer [Long]]
        case _: String   => a.asInstanceOf [ArrayBuffer [String]]
        case _  =>  println ("printInd: type not supported")
    }
    for (i <- b) print(v(i) + " ")  // Error: Any does not take parameters
}

I get an error on the print statement saying

Any does not take parameters    
print(v(i))  
      ^

v is of class ArrayBuffer so I am assuming it should take an integer parameter to return the element at that index. (Also I assume, if a(0) is Int, v is ArrayBuffer [Int]. Or is it still ArrayBuffer [Any]?).
Can anyone please explain what I am understanding wrong.

Upvotes: 0

Views: 794

Answers (2)

Andrey Tyukin
Andrey Tyukin

Reputation: 44908

The println statement returns a Unit. Thus, the type of v is inferred to be as a lower bound of ArrayBuffer[Int] and Unit, which is Any.

You can fix this as follows:

def printInd (a: ArrayBuffer [Any], b: Seq[Int]) = {
    val v = a(0) match {
        case _: Double   => a.asInstanceOf [ArrayBuffer [Double]]
        case _: Int      => a.asInstanceOf [ArrayBuffer [Int]]
        case _: Long     => a.asInstanceOf [ArrayBuffer [Long]]
        case _: String   => a.asInstanceOf [ArrayBuffer [String]]
        case _  =>  a
    }
    for (i <- b) print(v(i) + " ")
}

or like this:

def printInd (a: ArrayBuffer [Any], b: Seq[Int]) = {
    val v = a(0) match {
        case _: Double   => a.asInstanceOf [ArrayBuffer [Double]]
        case _: Int      => a.asInstanceOf [ArrayBuffer [Int]]
        case _: Long     => a.asInstanceOf [ArrayBuffer [Long]]
        case _: String   => a.asInstanceOf [ArrayBuffer [String]]
        case _  =>  throw new IllegalArgumentException("Unexpected type")
    }
    for (i <- b) print(v(i) + " ")
}

but in both cases, it doesn't buy you anything, because the most specific type that you can assign to v is still something like ArrayBuffer[_]. You have to do something with additional type information inside of the match, otherwise it's useless.

Upvotes: 3

airudah
airudah

Reputation: 1179

v is of type Any according to the error message.

You need to make your case _ => ... return an ArrayBuffer as well.

Upvotes: 0

Related Questions