From e755be5f7d0514ef00311a5c53deb2788d6dff94 Mon Sep 17 00:00:00 2001 From: realwunan Date: Tue, 16 Oct 2018 17:09:17 +0800 Subject: [PATCH 1/3] zh-cn for Scala Tour:extractor-objects.md --- _zh-cn/tour/extractor-objects.md | 54 +++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/_zh-cn/tour/extractor-objects.md b/_zh-cn/tour/extractor-objects.md index 39ce4bc90f..f7539ad827 100644 --- a/_zh-cn/tour/extractor-objects.md +++ b/_zh-cn/tour/extractor-objects.md @@ -1,6 +1,6 @@ --- layout: tour -title: Extractor Objects +title: 提取器对象 discourse: false @@ -13,3 +13,55 @@ language: zh-cn next-page: generic-classes previous-page: regular-expression-patterns --- + +提取器对象是一个包含有 `unapply` 方法的单例对象. `apply` 方法就像一个构造器, 接受参数然后创建一个实例对象, 反之 `unapply` 方法接受一个实例对象然后返回最初创建它所用的参数. 提取器常用在模式匹配和偏函数中. + +```tut +import scala.util.Random + +object CustomerID { + + def apply(name: String) = s"$name--${Random.nextLong}" + + def unapply(customerID: String): Option[String] = { + val stringArray: Array[String] = customerID.split("--") + if (stringArray.tail.nonEmpty) Some(stringArray.head) else None + } +} + +val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908 +customer1ID match { + case CustomerID(name) => println(name) // prints Sukyoung + case _ => println("Could not extract a CustomerID") +} +``` + +这里 `apply` 方法用 `name` 创建一个 `CustomerID` 字符串. 而 `unapply` 方法正好相反, 它返回 `name` . 当我们调用 `CustomerID("Sukyoung")` , 其实是调用了 `CustomerID.apply("Sukyoung")` 的简化语法. 当我们调用 `case CustomerID(name) => println(name)`, 就是在调用提取器方法. + +因为在定义一个值的时候可以使用一个模式来引入一个新的变量, 提取器可以用来初始化这个变量, 使用 unapply 方法来生成值. + +```tut +val customer2ID = CustomerID("Nico") +val CustomerID(name) = customer2ID +println(name) // prints Nico +``` + +上面的代码等价于 `val name = CustomerID.unapply(customer2ID).get`. + +```tut +val CustomerID(name2) = "--asdfasdfasdf" +``` + +如果没有匹配的值, 会抛出 `scala.MatchError`: + +```tut:fail +val CustomerID(name3) = "-asdfasdfasdf" +``` + +`unapply` 方法的返回值应当符合下面的某一条: + +* 如果只是用来测试, 返回一个 `Boolean` 类型的值. 例如 `case even()`. +* 如果只是用来提取单个 T 类型的值, 返回 `Option[T]`. +* 如果你想要提取多个值, 类型分别为 `T1,...,Tn`, 把它们放在一个可选的元祖中 `Option[(T1,...,Tn)]`. + +有时, 要提取的值的数量不是固定的, 因此我们想根据输入来返回随机数量的值. 这种情况下, 你可以用 `unapplySeq` 方法来定义提取器, 此方法返回 `Option[Seq[T]]`. 常见的例子有, 用 `case List(x, y, z) =>` 来解构一个列表 `List`, 以及用一个正则表达式 `Regex` 来分解一个字符串 `String`, 例如 `case r(name, remainingFields @ _*) =>`. From 8e21623bd586316af70e9d3c1a5a881a68682e1a Mon Sep 17 00:00:00 2001 From: realwunan Date: Tue, 4 Dec 2018 11:38:13 +0800 Subject: [PATCH 2/3] Fix some places according to liufengyun's suggestion --- _zh-cn/tour/extractor-objects.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/_zh-cn/tour/extractor-objects.md b/_zh-cn/tour/extractor-objects.md index f7539ad827..3816915603 100644 --- a/_zh-cn/tour/extractor-objects.md +++ b/_zh-cn/tour/extractor-objects.md @@ -14,7 +14,7 @@ next-page: generic-classes previous-page: regular-expression-patterns --- -提取器对象是一个包含有 `unapply` 方法的单例对象. `apply` 方法就像一个构造器, 接受参数然后创建一个实例对象, 反之 `unapply` 方法接受一个实例对象然后返回最初创建它所用的参数. 提取器常用在模式匹配和偏函数中. +提取器对象是一个包含有 `unapply` 方法的单例对象。`apply` 方法就像一个构造器,接受参数然后创建一个实例对象,反之 `unapply` 方法接受一个实例对象然后返回最初创建它所用的参数。提取器常用在模式匹配和偏函数中。 ```tut import scala.util.Random @@ -36,9 +36,9 @@ customer1ID match { } ``` -这里 `apply` 方法用 `name` 创建一个 `CustomerID` 字符串. 而 `unapply` 方法正好相反, 它返回 `name` . 当我们调用 `CustomerID("Sukyoung")` , 其实是调用了 `CustomerID.apply("Sukyoung")` 的简化语法. 当我们调用 `case CustomerID(name) => println(name)`, 就是在调用提取器方法. +这里 `apply` 方法用 `name` 创建一个 `CustomerID` 字符串。而 `unapply` 方法正好相反,它返回 `name` 。当我们调用 `CustomerID("Sukyoung")` ,其实是调用了 `CustomerID.apply("Sukyoung")` 的简化语法。当我们调用 `case CustomerID(name) => println(name)`,就是在调用提取器方法。 -因为在定义一个值的时候可以使用一个模式来引入一个新的变量, 提取器可以用来初始化这个变量, 使用 unapply 方法来生成值. +因为变量定义可以使用模式引入变量,提取器可以用来初始化这个变量,使用 unapply 方法来生成值。 ```tut val customer2ID = CustomerID("Nico") @@ -46,22 +46,22 @@ val CustomerID(name) = customer2ID println(name) // prints Nico ``` -上面的代码等价于 `val name = CustomerID.unapply(customer2ID).get`. +上面的代码等价于 `val name = CustomerID.unapply(customer2ID).get`。 ```tut val CustomerID(name2) = "--asdfasdfasdf" ``` -如果没有匹配的值, 会抛出 `scala.MatchError`: +如果没有匹配的值,会抛出 `scala.MatchError`: ```tut:fail val CustomerID(name3) = "-asdfasdfasdf" ``` -`unapply` 方法的返回值应当符合下面的某一条: +`unapply` 方法的返回值应当符合下面的某一条: -* 如果只是用来测试, 返回一个 `Boolean` 类型的值. 例如 `case even()`. -* 如果只是用来提取单个 T 类型的值, 返回 `Option[T]`. -* 如果你想要提取多个值, 类型分别为 `T1,...,Tn`, 把它们放在一个可选的元祖中 `Option[(T1,...,Tn)]`. +* 如果只是用来判断真假,返回一个 `Boolean` 类型的值。例如 `case even()`。 +* 如果只是用来提取单个 T 类型的值,返回 `Option[T]`。 +* 如果你想要提取多个值,类型分别为 `T1,...,Tn`,把它们放在一个可选的元组中 `Option[(T1,...,Tn)]`。 -有时, 要提取的值的数量不是固定的, 因此我们想根据输入来返回随机数量的值. 这种情况下, 你可以用 `unapplySeq` 方法来定义提取器, 此方法返回 `Option[Seq[T]]`. 常见的例子有, 用 `case List(x, y, z) =>` 来解构一个列表 `List`, 以及用一个正则表达式 `Regex` 来分解一个字符串 `String`, 例如 `case r(name, remainingFields @ _*) =>`. +有时,要提取的值的数量不是固定的,因此我们想根据输入来返回随机数量的值。这种情况下,你可以用 `unapplySeq` 方法来定义提取器,此方法返回 `Option[Seq[T]]`。常见的例子有,用 `case List(x, y, z) =>` 来解构一个列表 `List`,以及用一个正则表达式 `Regex` 来分解一个字符串 `String`,例如 `case r(name, remainingFields @ _*) =>`。 From 4c0a9860b3db1a8c88f476a891915efc4a724a32 Mon Sep 17 00:00:00 2001 From: realwunan Date: Tue, 4 Dec 2018 20:26:50 +0800 Subject: [PATCH 3/3] Fix one place according to heping1989's suggestion --- _zh-cn/tour/extractor-objects.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_zh-cn/tour/extractor-objects.md b/_zh-cn/tour/extractor-objects.md index 3816915603..457bb36ca0 100644 --- a/_zh-cn/tour/extractor-objects.md +++ b/_zh-cn/tour/extractor-objects.md @@ -60,8 +60,8 @@ val CustomerID(name3) = "-asdfasdfasdf" `unapply` 方法的返回值应当符合下面的某一条: -* 如果只是用来判断真假,返回一个 `Boolean` 类型的值。例如 `case even()`。 -* 如果只是用来提取单个 T 类型的值,返回 `Option[T]`。 -* 如果你想要提取多个值,类型分别为 `T1,...,Tn`,把它们放在一个可选的元组中 `Option[(T1,...,Tn)]`。 +* 如果只是用来判断真假,可以返回一个 `Boolean` 类型的值。例如 `case even()`。 +* 如果只是用来提取单个 T 类型的值,可以返回 `Option[T]`。 +* 如果你想要提取多个值,类型分别为 `T1,...,Tn`,可以把它们放在一个可选的元组中 `Option[(T1,...,Tn)]`。 有时,要提取的值的数量不是固定的,因此我们想根据输入来返回随机数量的值。这种情况下,你可以用 `unapplySeq` 方法来定义提取器,此方法返回 `Option[Seq[T]]`。常见的例子有,用 `case List(x, y, z) =>` 来解构一个列表 `List`,以及用一个正则表达式 `Regex` 来分解一个字符串 `String`,例如 `case r(name, remainingFields @ _*) =>`。