众所周知,程序员可以使用val
或var
在Scala中声明一个新变量,如下所示:
val x = 10 //x is now defined and an Integer.
函数参数还引入了一个新变量:
def fun(y: String) {
//y of type String is now available here
}
这些是直截了当的例子。但是,有更多方法可以在给定的上下文中声明变量。
例如,match
表达式也可以引入新变量:
val z = 10
z match {
case w: Int => w //w is a valid variable of type Int in this scope
}
在Scala中将变量引入特定范围的其他命令是什么?
感兴趣的背景:
我在宏中使用它,在抽象语法树中查找变量定义(ValDefs)。 match
表达式或函数定义生成与普通ValDefs不同的语法树,我必须要处理它。由于我希望我的宏是健壮的,我想针对所有可能形式的变量声明进行测试。
评论说明:
def
的方法定义无关紧要。此外,我只对源代码中可见的变量感兴趣,并且可以通过某些术语引用。
答案 0 :(得分:6)
以下列出了我所知道的可能不同的一切; x
是创建的变量:
// 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)
答案 1 :(得分:1)
解构后绑定:
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. */ }
无可辩驳的模式匹配:
val (r, s, t) = (53, 17.0 * 3 + 2, "LIII")
/* r, s and t are bound here as Int, Double and String, resp. */