From c0d87d510b6e36139f2d5556b808f602a7141de8 Mon Sep 17 00:00:00 2001 From: Zheng Ping Date: Fri, 4 Aug 2017 10:07:21 +0800 Subject: [PATCH 1/2] Update ch19-03-advanced-traits.md --- src/ch19-03-advanced-traits.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ch19-03-advanced-traits.md b/src/ch19-03-advanced-traits.md index 855d452..df022f4 100644 --- a/src/ch19-03-advanced-traits.md +++ b/src/ch19-03-advanced-traits.md @@ -10,7 +10,7 @@ **关联类型**(*associated types*)是一个将类型占位符与 trait 相关联的方式,这样 trait 的方法签名中就可以使用这些占位符类型。实现一个 trait 的人只需要针对专门的实现在这个类型的位置指定相应的类型即可。 -本章描述的大部分内容都非常少见。关联类型则比较适中;他们比本书其他的内容要少见,不过比本章中的很多内容要更常见。 +本章描述的大部分内容都非常少见。关联类型则比较适中;它们比本书其他的内容要少见,不过比本章中的很多内容要更常见。 一个带有关联类型的 trait 的例子是标准库提供的 `Iterator` trait。它有一个叫做 `Item` 的关联类型来替代遍历的值的类型。第十三章曾提到过 `Iterator` trait 的定义如列表 19-20 所示: @@ -23,7 +23,7 @@ pub trait Iterator { 列表 19-20:`Iterator` trait 的定义中带有关联类型 `Item` -这就是说 `Iterator` trait 有一个关联类型 `Item`。`Item` 是一个占位类型,同时 `next` 方法会返回 `Option` 类型的值。这个 trait 的实现者会指定 `Item` 的具体类型,而不管实现者指定何种类型, `next` 方法都会返回一个包含了这种类型值的 `Option`。 +这就是说 `Iterator` trait 有一个关联类型 `Item`。`Item` 是一个占位类型,同时 `next` 方法会返回 `Option` 类型的值。这个 trait 的实现者会指定 `Item` 的具体类型,然而不管实现者指定何种类型, `next` 方法都会返回一个包含了这种类型值的 `Option`。 #### 关联类型 vs 泛型 @@ -36,7 +36,7 @@ impl Iterator for Counter { fn next(&mut self) -> Option { ``` -这感觉类似于泛型。那么为什么 `Iterator` trait 不定义为如列表 19-21 所示这样呢? +这感觉类似于泛型。那么为什么 `Iterator` trait 不像列表 19-21 那样定义呢? ```rust pub trait Iterator { @@ -79,7 +79,7 @@ fn distance>(graph: &G, start: &N, end: &N) -> u32 { 列表 19-23:`distance` 函数的签名,它使用 `GGraph` trait 并必须指定所有的泛型参数 -函数需要指定泛型参数 `N`、`E` 和 `G`,其中 `G` 拥有以 `N` 类型作为 `Node` 和 `E` 类型作为 `Edge` 的 `GGraph` trait 作为 trait bound。即便 `distance` 函数无需指定边的类型,我们也强制声明了 `E` 参数,因为需要使用 `GGraph` trait 而这样一来需要指定 `Edge` 的类型。 +函数需要指定泛型参数 `N`、`E` 和 `G`,其中 `G` 拥有以 `N` 类型作为 `Node` 和 `E` 类型作为 `Edge` 的 `GGraph` trait 作为 trait bound。即便 `distance` 函数无需指定边的类型,我们也强制声明了 `E` 参数,因为需要使用 `GGraph` trait, 而 `GGraph` 需要指定 `Edge` 的类型。 与此相对,列表 19-24 中的 `distance` 定义使用列表 19-22 中带有关联类型的 `AGraph` trait: From 4fce17d4f9ab2a9c97f14ab64a733af2d9cef941 Mon Sep 17 00:00:00 2001 From: Zheng Ping Date: Thu, 10 Aug 2017 22:47:52 +0800 Subject: [PATCH 2/2] Update ch19-03-advanced-traits.md --- src/ch19-03-advanced-traits.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ch19-03-advanced-traits.md b/src/ch19-03-advanced-traits.md index df022f4..c3e7bed 100644 --- a/src/ch19-03-advanced-traits.md +++ b/src/ch19-03-advanced-traits.md @@ -100,7 +100,7 @@ fn distance(graph: &G, start: &G::Node, end: &G::Node) -> u32 { #### 带有关联类型的 trait 对象 -你可能会好奇为什么不在列表 19-23 和 19-24 的 `distance` 函数中使用 trait 对象。当使用 trait 对象时使用泛型 `GGraph` trait 的 `distance` 函数的签名确实跟准确了一些: +你可能会好奇为什么不在列表 19-23 和 19-24 的 `distance` 函数中使用 trait 对象。当使用 trait 对象时使用泛型 `GGraph` trait 的 `distance` 函数的签名确实更准确了一些: ```rust # trait GGraph {} @@ -114,7 +114,7 @@ fn distance(graph: &GGraph, start: &N, end: &N) -> u32 { 不可能改变列表 19-24 来对图使用 trait 对象,因为这样就无法引用 `AGraph` trait 中的关联类型。 -但是一般而言使用带有关联类型的 trait 的 trait 对象是可能;列表 19-25 展示了一个函数 `traverse` ,它无需在其他参数中使用关联类型。然而这种情况必须指定关联类型的具体类型。这里选择接受以 `usize` 作为 `Node` 和以两个 `usize` 值的元组作为 `Edge` 的实现了 `AGraph` trait 的类型: +但是一般而言常见的情形是使用带有关联类型 trait 的 trait 对象;列表 19-25 展示了一个函数 `traverse` ,它无需在其他参数中使用关联类型。然而这种情况必须指定关联类型的具体类型。这里选择接受以 `usize` 作为 `Node` 和以两个 `usize` 值的元组作为 `Edge` 的实现了 `AGraph` trait 的类型: ```rust # trait AGraph { @@ -125,7 +125,7 @@ fn distance(graph: &GGraph, start: &N, end: &N) -> u32 { fn traverse(graph: &AGraph) {} ``` -虽然 trait 对象意味着无需在编译时就知道 `graph` 参数的具体类型,但是我们确实需要在 `traverse` 函数中通过具体的关联类型来限制 `AGraph` trait 的使用。如果不提供这样的限制,Rust 将不能计算出用哪个 `impl` 来匹配这个 trait 对象,因为关联类型可以作为方法签名的一部分,Rust 需要在虚函数表中寻找他们。 +虽然 trait 对象意味着无需在编译时就知道 `graph` 参数的具体类型,但是我们确实需要在 `traverse` 函数中通过具体的关联类型来限制 `AGraph` trait 的使用。如果不提供这样的限制,Rust 将不能计算出用哪个 `impl` 来匹配这个 trait 对象,因为关联类型可以作为方法签名的一部分,Rust 需要在虚函数表(vtable)中查找它们。 ### 运算符重载和默认类型参数