当在 class 之外使用 case class 构造函数参数时,它叫什么?

What is it called when a case class constructor param is used outside the class?

下面第 9 行发生了什么使得 result 变量在第 10 行可访问?

示例来自 Akka documentation on testing. The Ask in line eight returns a scala.concurrent.Future. The Future.value() returns an Option[Try[T]],它将是 Some(Success(t))Some(Failure(error))。然后调用 Some.get,这应该是 return 或 t 或错误,具体取决于 Try 的结果。

似乎第 9 行 future.value.get 的值是否是一个错误,它正在尝试实例化一个新的 Success,which is defined as a case class in Try,其中的 return 值Some.get。第九行的 Success 没有直接使用,而是 case class 构造函数参数 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)

这叫做Pattern Matching

val Success( result: Int ) = future.value.get 是模式匹配。您可以在声明 val 时使用模式匹配为标识符赋值。写法差不多:

val result: Int = future.value.get match {
    case Success(r: Int) => r
}

请注意,这不是一个详尽的匹配,如果 future.value.getFailure,那么将抛出 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

那只是模式匹配。例如:

 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 方法(它是伴随对象的一部分,为情况 class 自动生成)被调用。

一般来说,对于像 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