Reputation: 4009
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
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
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