2

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
}
1
  • @chengpohi Can you elaborate? Commented Apr 26, 2015 at 13:14

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

But i think the type of allF is known at compile time
It is (assuming they are declared in the same scope), but there is no syntax to say "make this variable the same type as that one" except the multi-variable declaration I mention in my answer.
I think you are misunderstanding the use of scala matching. In your new example, the type of the variable y would have to be specified in advance, or would have to be _, which would match anything. You cannot ask for y to be "whatever allF is"
@ChrisShain, I think it's a legitimate question, though. One could envisage a syntax like val b:a.type (as long as the type of a is statically known), You can do this (although not with a and b in the same scope) by something like val a: some-type; ..; def foo[A](x:A) = { val b: A ...}; foo(a) where b ends up with the type of a
1

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.

Comments

0

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"
  }

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.