lovesh
lovesh

Reputation: 5411

Declare a variable in Scala whose type is same as another variable

Lets say i have a variable

val allF = (Some(1), "some string", 2.99, "another string", 1, Some(30))

Now i want to declare a few more variables of type same as allF i.e. (Some[Int], String, Double, String, Int, Some[Int]). I can do

var a1: (Some[Int], String, Double, String, Int, Some[Int]) = _
var a2: (Some[Int], String, Double, String, Int, Some[Int]) = _
... and so on

or i can do

type T = (Some[Int], String, Double, String, Int, Some[Int])
var a1: T = _
var a2: T = _
.. and do on

Is there some way i can use the variable allF to get its type and declare variables a1, a2, a3, ... like this

val allF = (Some(1), "some string", 2.99, "another string", 1, Some(30))
var a1: typeof(allF) = _
var a2: typeof(allF) = _
...

UPDATE - Also for situations like this

val allF = (Some(1), "some string", 2.99, "another string", 1, Some(30))
 xyz match {
   case y: (???)\\ if y is of the same type as allF
}

Upvotes: 2

Views: 860

Answers (4)

Chandra
Chandra

Reputation: 21

If you want default value of same ref type just define a fun and use it as follows:

def dval[T >: Null](x : T): T  = { null }

val a1 = dval(allF)

Upvotes: 0

Stefan Sigurdsson
Stefan Sigurdsson

Reputation: 221

I understood the question to be, is there a convenient compiler directive to define the type of a variable b to be the same as the type inferred for the variable a. If this is correctly understood then I think the answer is simply no.

It is possible to name a type explicitly, or have the type inferred at compile time, but it is not possible to define a variable by referring to the type inferred for a different variable. Scala doesn't have any language constructs for doing this. (I actually don't know about any language that supports this.)

It is possible to force the two variables to be of the same type by simply assigning the value of a to b, and then reassigning b with the right value. But it might be best to just define the type explicitly and refer to it by name - the code would almost certainly be more maintainable in the long run, if that is a concern. And if a and b are vals then this assignment trick will obviously not work.

Upvotes: 1

Brendan
Brendan

Reputation: 136

You can definitely proceed in the second manner you proposed. To address your update on case matching you can do something as such:

  object MyTypes {
    type F = (Some[Int], String, Double, String, Int, Some[Int])
    type G = (Some[Int], Long, Double, Long, Int, Some[Int])

  }
  val allF: MyTypes.F  = (Some(1), "some string", 2.99, "another string", 1, Some(30))
  val allG: MyTypes.G = (Some(1), 101, 2.99, 9999999, 1, Some(30))


  import scala.reflect.runtime.universe._ //This allows typeOf[] and etc
  val tuple = allF
  typeOf[tuple.type] match {
    case fType if fType =:= typeOf[MyTypes.F] => "do something 1"
    case gType if gType =:= typeOf[MyTypes.G] => "do something 2"
  }

That or you just do something more standard and not quite as advanced in the type system:

  val allF = (Some(1), "some string", 2.99, "another string", 1, Some(30))
  val allG = (Some(1), 101, 2.99, 9999999, 1, Some(30))

  val tuple: (_, _, _, _, _, _) = allF
  tuple match {
    case (x1: Some[Int], x2: String, x3: Double, x4: String, x5: Int, x6: Some[Int]) => "do something 1"
    case (x1: Some[Int], x2: Long, x3: Double, x4: Long, x5: Int, x6: Some[Int]) => "do something 2"
    case _ => "Handle not found"
  }

Upvotes: 0

Chris Shain
Chris Shain

Reputation: 51369

It depends on what you mean.

If you literally want to declare all of the variables in the same scope, as per your example, you can do that:

  var a, b, c = (5,4,3,2,1) // All have the same type and value

But if you are saying that you want to create a variable which has the same type as a variable whose type you don't know at compile time (maybe an AnyRef passed as a parameter), then you are subject to the same restrictions as in Java (or any other statically-typed language). You can create the variable via reflection, but you can only act on it as an object.

Upvotes: 1

Related Questions