当在 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.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
那只是模式匹配。例如:
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
下面第 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.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
那只是模式匹配。例如:
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