Emiswelt
Emiswelt

Reputation: 4009

Which ways to introduce a new variable in Scala exist?

It is well-known that a programmer can declare a new variable in Scala by using val or var, like this:

val x = 10 //x is now defined and an Integer.

A function parameter also introduces a new variable:

def fun(y: String) {
    //y of type String is now available here
}

These are straight forward examples. However, there are more ways to declare a variable in a given context.

For instance, a match expression can also introduce new variables:

val z = 10
z match {
     case w: Int => w //w is a valid variable of type Int in this scope
}

What are further commands which introduce variables into a certain scope in Scala?

Background for the interested:

I'm using this in a macro which finds variable definitions (ValDefs) in the abstract syntax tree. match expressions or function definitions generate a different syntax tree than normal ValDefs, which I have to take care of. Since I want my macro to be robust, I want to test it against all possible forms of variable declarations.

Notes on comments:

Method definitions with def are not of concern. Furthermore, I am only interested in variables which are visible in the source code and can be referenced by some term.

Upvotes: 1

Views: 163

Answers (2)

Rex Kerr
Rex Kerr

Reputation: 167911

Here's a list of everything I know of that might be different; x is the variable created:

// Within a block
val x = 5
var x = 5
lazy val x = 5
def x = 5
object x { val value = 5 }
val MyCaseClass(x, _) = oneOfMyCaseClasses
val MyCaseClass(_, Another(x)) = foo
val MyCaseClass(_, x @ Another(_)) = foo

// Functions
m.map( x => bar(x) )
m.map( (x: Int) => bar(x) )

// Functions that destructure
m.map{ case y if foo(y) => baz; case x => bar(x) }
m.map{ case Option(x) => bar(x) }
m.map{ case Option(List(x)) => bar(x) }
m.map{ case Option(x @ List(_)) => foo(x) }

// Partial functions with/without destructuring
m.collect{ case x => bar(x) }
m.collect{ case Option(List(x)) => bar(x) }
m.collect{ case Option(x @ List(_)) => foo(x) }

// For comprehensions
for (x <- xs)
for (y <- ys; x = foo(y))
for ((x, _) <- zs)
for ((_, y @ Option(_)) <- ws)

// Method arguments
def foo(x: Int) = 
def foo(y: Int)(implicit x: Foo) =
class Foo(x: Int)
class Foo(val x: Int)
class Foo(var x: Int)
case class Foo(x: Int)
case class Foo(var x: Int)

Upvotes: 6

Randall Schulz
Randall Schulz

Reputation: 26486

Destructuring Bind:

case class CaseClassFiftyThree(x: Double, y: Long, z: String)
...
someValue match { case CaseClassFiftyThree(x, y, z) =>
  /* x, y and z are bound here as Double, Long and String, resp. */ }

Irrefutable Pattern Match:

val (r, s, t) = (53, 17.0 * 3 + 2, "LIII")

/* r, s and t are bound here as Int, Double and String, resp. */

Upvotes: 1

Related Questions