Skip to content

Commit e8ca5da

Browse files
authored
Merge pull request #1199 from realwunan/lower-type-bounds
Simplify Chinese translation of Scala Tour: lower-type-bounds.md
2 parents cbe7216 + 8c4f691 commit e8ca5da

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

_zh-cn/tour/lower-type-bounds.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: tour
3-
title: Lower Type Bounds
3+
title: 类型下界
44

55
discourse: false
66

@@ -13,3 +13,58 @@ language: zh-cn
1313
next-page: inner-classes
1414
previous-page: upper-type-bounds
1515
---
16+
17+
[类型上界](upper-type-bounds.html) 将类型限制为另一种类型的子类型,而 *类型下界* 将类型声明为另一种类型的超类型。 术语 `B >: A` 表示类型参数 `B` 或抽象类型 `B` 是类型 `A` 的超类型。 在大多数情况下,`A` 将是类的类型参数,而 `B` 将是方法的类型参数。
18+
19+
下面看一个宜用类型下届的例子:
20+
21+
```tut:fail
22+
trait Node[+B] {
23+
def prepend(elem: B): Node[B]
24+
}
25+
26+
case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
27+
def prepend(elem: B): ListNode[B] = ListNode(elem, this)
28+
def head: B = h
29+
def tail: Node[B] = t
30+
}
31+
32+
case class Nil[+B]() extends Node[B] {
33+
def prepend(elem: B): ListNode[B] = ListNode(elem, this)
34+
}
35+
```
36+
37+
该程序实现了一个单链表。 `Nil` 表示空元素(即空列表)。 `class ListNode` 是一个节点,它包含一个类型为 `B` (`head`) 的元素和一个对列表其余部分的引用 (`tail`)。 `class Node` 及其子类型是协变的,因为我们定义了 `+B`
38+
39+
但是,这个程序 _不能_ 编译,因为方法 `prepend` 中的参数 `elem`**变的 `B` 类型。 这会出错,因为函数的参数类型是**变的,而返回类型是**变的。
40+
41+
要解决这个问题,我们需要将方法 `prepend` 的参数 `elem` 的型变翻转。 我们通过引入一个新的类型参数 `U` 来实现这一点,该参数具有 `B` 作为类型下界。
42+
43+
```tut
44+
trait Node[+B] {
45+
def prepend[U >: B](elem: U): Node[U]
46+
}
47+
48+
case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
49+
def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this)
50+
def head: B = h
51+
def tail: Node[B] = t
52+
}
53+
54+
case class Nil[+B]() extends Node[B] {
55+
def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this)
56+
}
57+
```
58+
59+
现在我们像下面这么做:
60+
```tut
61+
trait Bird
62+
case class AfricanSwallow() extends Bird
63+
case class EuropeanSwallow() extends Bird
64+
65+
66+
val africanSwallowList= ListNode[AfricanSwallow](AfricanSwallow(), Nil())
67+
val birdList: Node[Bird] = africanSwallowList
68+
birdList.prepend(new EuropeanSwallow)
69+
```
70+
可以为 `Node[Bird]` 赋值 `africanSwallowList`,然后再加入一个 `EuropeanSwallow`

0 commit comments

Comments
 (0)