From 7c0538439fd22334ca7f711cc1aaa5df4b2cf07c Mon Sep 17 00:00:00 2001 From: realwunan Date: Sat, 3 Nov 2018 17:44:34 +0800 Subject: [PATCH 1/3] Simplify Chinese translation of Scala Tour: type-inference.md --- _zh-cn/tour/type-inference.md | 64 ++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/_zh-cn/tour/type-inference.md b/_zh-cn/tour/type-inference.md index f2f4581966..4d8c1efbdb 100644 --- a/_zh-cn/tour/type-inference.md +++ b/_zh-cn/tour/type-inference.md @@ -1,6 +1,6 @@ --- layout: tour -title: Type Inference +title: 类型推断 discourse: false @@ -13,3 +13,65 @@ language: zh-cn next-page: operators previous-page: polymorphic-methods --- + +Scala 编译器通常可以推断出表达式的类型,因此你不必显式地声明它。 + +## 省略类型 + +```tut +val businessName = "Montreux Jazz Café" +``` +编译器可以发现 `businessName` 是 String 类型。 它的工作原理和方法类似: + +```tut +def squareOf(x: Int) = x * x +``` +编译器可以推断出方法的返回类型为 `Int`,因此不需要明确地声明返回类型。 + +对于递归方法,编译器无法推断出结果类型。 下面这个程序就是由于这个原因而编译失败: + +```tut:fail +def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) +``` + +当调用 [多态方法](polymorphic-methods.html) 或实例化 [泛型类](generic-classes.html) 时,也不必明确指定类型参数。 Scala 编译器将从上下文和实际方法的类型/构造函数参数的类型推断出缺失的类型参数。 + +看下面两个例子: + +```tut +case class MyPair[A, B](x: A, y: B); +val p = MyPair(1, "scala") // type: MyPair[Int, String] + +def id[T](x: T) = x +val q = id(1) // type: Int +``` + +编译器使用参数 `MyPair` 的类型来推断出 `A` 和 `B` 的类型。对于 `x` 的类型同样如此。 + +## 参数 + +编译器从不推断方法参数的类型。 但是,在某些情况下,当函数作为参数传递时,它可以推断出匿名函数参数类型。 + +```tut +Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) +``` + +方法 map 的参数是 `f: A => B`。 因为我们把整数放在 `Seq` 中,编译器知道 `A` 是 `Int` 类型 (即 `x` 是一个整数)。 因此,编译器可以从 `x * 2` 推断出 `B` 是 `Int` 类型。 + +## 何时 _不要_ 依赖类型推断 + +通常认为声明在公共 API 中的成员类型更具可读性。 因此,我们建议你为将在你的代码中向用户公开的任何 API 明确指定类型。 + +此外,类型推断有时会推断出太具体的类型。 假设我们这么写: + +```tut +var obj = null +``` + +我们就不能继续重新分配值: + +```tut:fail +obj = new AnyRef +``` + +它不能编译,因为 `obj` 推断出的类型是 `Null`。 由于该类型的唯一值是 `null`,因此无法分配其他的值。 From 732f3a28b3ee3575b48064c64c24ce6353dab16e Mon Sep 17 00:00:00 2001 From: realwunan Date: Fri, 30 Nov 2018 20:28:49 +0800 Subject: [PATCH 2/3] Fix Simplify Chinese translation of Scala Tour: type-inference according to liufengyu's suggestion --- _zh-cn/tour/type-inference.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_zh-cn/tour/type-inference.md b/_zh-cn/tour/type-inference.md index 4d8c1efbdb..c3f62acf12 100644 --- a/_zh-cn/tour/type-inference.md +++ b/_zh-cn/tour/type-inference.md @@ -46,21 +46,21 @@ def id[T](x: T) = x val q = id(1) // type: Int ``` -编译器使用参数 `MyPair` 的类型来推断出 `A` 和 `B` 的类型。对于 `x` 的类型同样如此。 +编译器使用传给 `MyPair` 参数的类型来推断出 `A` 和 `B` 的类型。对于 `x` 的类型同样如此。 ## 参数 -编译器从不推断方法参数的类型。 但是,在某些情况下,当函数作为参数传递时,它可以推断出匿名函数参数类型。 +编译器从不推断方法形式参数的类型。 但是,在某些情况下,当函数作为参数传递时,编译器可以推断出匿名函数形式参数的类型。 ```tut Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) ``` -方法 map 的参数是 `f: A => B`。 因为我们把整数放在 `Seq` 中,编译器知道 `A` 是 `Int` 类型 (即 `x` 是一个整数)。 因此,编译器可以从 `x * 2` 推断出 `B` 是 `Int` 类型。 +方法 map 的形式参数是 `f: A => B`。 因为我们把整数放在 `Seq` 中,编译器知道 `A` 是 `Int` 类型 (即 `x` 是一个整数)。 因此,编译器可以从 `x * 2` 推断出 `B` 是 `Int` 类型。 ## 何时 _不要_ 依赖类型推断 -通常认为声明在公共 API 中的成员类型更具可读性。 因此,我们建议你为将在你的代码中向用户公开的任何 API 明确指定类型。 +通常认为,公开可访问的 API 成员应该具有显示类型声明。 因此,我们建议你为将在你的代码中向用户公开的任何 API 明确指定类型。 此外,类型推断有时会推断出太具体的类型。 假设我们这么写: @@ -68,7 +68,7 @@ Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) var obj = null ``` -我们就不能继续重新分配值: +我们就不能进行重新赋值: ```tut:fail obj = new AnyRef From fdad7cdbbfb932dabfe9a3d6cfd82585b46fa7f2 Mon Sep 17 00:00:00 2001 From: Fengyun Liu Date: Fri, 30 Nov 2018 13:48:37 +0100 Subject: [PATCH 3/3] Small fix --- _zh-cn/tour/type-inference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_zh-cn/tour/type-inference.md b/_zh-cn/tour/type-inference.md index c3f62acf12..8169252b17 100644 --- a/_zh-cn/tour/type-inference.md +++ b/_zh-cn/tour/type-inference.md @@ -60,7 +60,7 @@ Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) ## 何时 _不要_ 依赖类型推断 -通常认为,公开可访问的 API 成员应该具有显示类型声明。 因此,我们建议你为将在你的代码中向用户公开的任何 API 明确指定类型。 +通常认为,公开可访问的 API 成员应该具有显示类型声明以增加可读性。 因此,我们建议你将代码中向用户公开的任何 API 明确指定类型。 此外,类型推断有时会推断出太具体的类型。 假设我们这么写: