下面第九行会发生什么使得result
变量可以在第十行访问?
示例来自Akka documentation on testing。第8行中的Ask
返回scala.concurrent.Future
。 Future.value()
会返回Option [Try [T]],其中包含Some(Success(t))
或Some(Failure(error))
。然后调用Some.get
,应该返回t
或错误,具体取决于Try
的结果。
似乎future.value.get
的值是否是第9行中的错误,它试图使用Some.get
的返回值来实例化新的成功which is defined as a case class in Try。第九行的Success不是直接使用的,而是case类的构造函数参数result
以某种方式使它成为范围,因此它可以在第十行中使用。这在Scala中被称为什么?我在哪里可以找到有关此语法如何工作的更多信息?
1. import akka.testkit.TestActorRef
2. import scala.concurrent.duration._
3. import scala.concurrent.Await
4. import akka.pattern.ask
5.
6. val actorRef = TestActorRef(newMyActor)
7. // hypothetical message stimulating a '42' answer
8. val future = actorRef ? Say42
9. val Success( result: Int ) = future.value.get
10. result should be (42)
答案 0 :(得分:3)
val Success( result: Int ) = future.value.get
是模式匹配。在声明val时,可以使用模式匹配为标识符赋值。它和写作一样:
val result: Int = future.value.get match {
case Success(r: Int) => r
}
请注意,这不是一个详尽的匹配,如果future.value.get
是Failure
,则会抛出MatchError
。在单元测试的上下文中,我一直使用这样的模式匹配,因为MatchError
将是失败的另一种指示。
以下是类似(更安全)模式匹配分配的几个示例:
val (a, b) = (1, 2)
case class Test(i: Int, j: String)
val test = Test(1, "a")
val (i, j) = test
val list = List(1, 2, 3, 4)
val List(first, second, _*) = list // though this will fail if the List has less than 3 elements
答案 1 :(得分:1)
那只是模式匹配。例如:
scala> val Some(a) = Some(5)
a: Int = 5
scala> val Some(a) = None: Option[Int]
scala.MatchError: None (of class scala.None$)
... 33 elided
相当于:
scala> val a = Some(5) match {case Some(a) => a}
a: Int = 5
scala> val a = (None: Option[Int]) match {case Some(a) => a}
scala.MatchError: None (of class scala.None$)
... 33 elided
在两种情况下调用Some.unapply
方法(它是伴随对象的一部分,为案例类自动生成)。
通常,对于像val Extractor(a, Extractor(b, c)) = input
这样的表达式,scala-compiler在内部生成(可以用宏检查)特殊的合成表达式:
val tuple = input match { //synthetic value here
Extractor(a, Extractor(b, c)) => (a,b,c)
}
val a = tuple._1
val b = tuple._2
val c = tuple._3
答案 2 :(得分:0)
这称为Pattern Matching。