在Scala中引入新变量的方法有哪些?

时间:2014-08-01 21:14:33

标签: scala variable-declaration

众所周知,程序员可以使用valvar在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的方法定义无关紧要。此外,我只对源代码中可见的变量感兴趣,并且可以通过某些术语引用。

2 个答案:

答案 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. */