1
1
---
2
2
layout : tour
3
- title : Extractor Objects
3
+ title : 提取器对象
4
4
5
5
discourse : false
6
6
@@ -13,3 +13,55 @@ language: zh-cn
13
13
next-page : generic-classes
14
14
previous-page : regular-expression-patterns
15
15
---
16
+
17
+ 提取器对象是一个包含有 ` unapply ` 方法的单例对象. ` apply ` 方法就像一个构造器, 接受参数然后创建一个实例对象, 反之 ` unapply ` 方法接受一个实例对象然后返回最初创建它所用的参数. 提取器常用在模式匹配和偏函数中.
18
+
19
+ ``` tut
20
+ import scala.util.Random
21
+
22
+ object CustomerID {
23
+
24
+ def apply(name: String) = s"$name--${Random.nextLong}"
25
+
26
+ def unapply(customerID: String): Option[String] = {
27
+ val stringArray: Array[String] = customerID.split("--")
28
+ if (stringArray.tail.nonEmpty) Some(stringArray.head) else None
29
+ }
30
+ }
31
+
32
+ val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908
33
+ customer1ID match {
34
+ case CustomerID(name) => println(name) // prints Sukyoung
35
+ case _ => println("Could not extract a CustomerID")
36
+ }
37
+ ```
38
+
39
+ 这里 ` apply ` 方法用 ` name ` 创建一个 ` CustomerID ` 字符串. 而 ` unapply ` 方法正好相反, 它返回 ` name ` . 当我们调用 ` CustomerID("Sukyoung") ` , 其实是调用了 ` CustomerID.apply("Sukyoung") ` 的简化语法. 当我们调用 ` case CustomerID(name) => println(name) ` , 就是在调用提取器方法.
40
+
41
+ 因为在定义一个值的时候可以使用一个模式来引入一个新的变量, 提取器可以用来初始化这个变量, 使用 unapply 方法来生成值.
42
+
43
+ ``` tut
44
+ val customer2ID = CustomerID("Nico")
45
+ val CustomerID(name) = customer2ID
46
+ println(name) // prints Nico
47
+ ```
48
+
49
+ 上面的代码等价于 ` val name = CustomerID.unapply(customer2ID).get ` .
50
+
51
+ ``` tut
52
+ val CustomerID(name2) = "--asdfasdfasdf"
53
+ ```
54
+
55
+ 如果没有匹配的值, 会抛出 ` scala.MatchError ` :
56
+
57
+ ``` tut:fail
58
+ val CustomerID(name3) = "-asdfasdfasdf"
59
+ ```
60
+
61
+ ` unapply ` 方法的返回值应当符合下面的某一条:
62
+
63
+ * 如果只是用来测试, 返回一个 ` Boolean ` 类型的值. 例如 ` case even() ` .
64
+ * 如果只是用来提取单个 T 类型的值, 返回 ` Option[T] ` .
65
+ * 如果你想要提取多个值, 类型分别为 ` T1,...,Tn ` , 把它们放在一个可选的元祖中 ` Option[(T1,...,Tn)] ` .
66
+
67
+ 有时, 要提取的值的数量不是固定的, 因此我们想根据输入来返回随机数量的值. 这种情况下, 你可以用 ` unapplySeq ` 方法来定义提取器, 此方法返回 ` Option[Seq[T]] ` . 常见的例子有, 用 ` case List(x, y, z) => ` 来解构一个列表 ` List ` , 以及用一个正则表达式 ` Regex ` 来分解一个字符串 ` String ` , 例如 ` case r(name, remainingFields @ _*) => ` .
0 commit comments