mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2024-11-09 08:51:18 +08:00
commit
6184d6db5c
@ -61,7 +61,7 @@ names and the types in their signatures</span>
|
|||||||
|
|
||||||
为了参数化要定义的函数的签名中的类型,我们需要像给函数的值参数起名那样为这类型参数起一个名字。这里选择了名称`T`。任何标识符都可以作为类型参数名,选择`T`是因为 Rust 的类型命名规范是骆驼命名法(CamelCase)。另外泛型类型参数的规范也倾向于简短,经常仅仅是一个字母。`T`作为“type”的缩写是大部分 Rust 程序员的首选。
|
为了参数化要定义的函数的签名中的类型,我们需要像给函数的值参数起名那样为这类型参数起一个名字。这里选择了名称`T`。任何标识符都可以作为类型参数名,选择`T`是因为 Rust 的类型命名规范是骆驼命名法(CamelCase)。另外泛型类型参数的规范也倾向于简短,经常仅仅是一个字母。`T`作为“type”的缩写是大部分 Rust 程序员的首选。
|
||||||
|
|
||||||
当需要再函数体中使用一个参数时,必须在函数签名中声明这个参数以便编译器能知道函数体中这个名称的意义。同理,当在函数签名中使用一个类型参数时,必须在使用它之前就声明它。类型参数声明位于函数名称与参数列表中间的尖括号中。
|
当需要在函数体中使用一个参数时,必须在函数签名中声明这个参数以便编译器能知道函数体中这个名称的意义。同理,当在函数签名中使用一个类型参数时,必须在使用它之前就声明它。类型参数声明位于函数名称与参数列表中间的尖括号中。
|
||||||
|
|
||||||
我们将要定义的泛型版本的`largest`函数的签名看起来像这样:
|
我们将要定义的泛型版本的`largest`函数的签名看起来像这样:
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ error[E0369]: binary operation `>` cannot be applied to type `T`
|
|||||||
note: an implementation of `std::cmp::PartialOrd` might be missing for `T`
|
note: an implementation of `std::cmp::PartialOrd` might be missing for `T`
|
||||||
```
|
```
|
||||||
|
|
||||||
注释中提到了`std::cmp::PartialOrd`,这是一个 *trait*。下一部分会讲到 trait,不过简单来说,这个错误表明`largest`的函数体对`T`的所有可能的类型都无法工作;因为在函数体需要比较`T`类型的值,不过它只能用于我们知道如何排序的类型。标准库中定义的`std::cmp::PartialOrd` trait 可以实现类型的排序功能。在下一部分会再次回到 trait 并讲解如何为泛型指定一个 trait,不过让我们先把这个例子放在一边并探索其他那些可以使用泛型类型参数的地方。
|
注释中提到了`std::cmp::PartialOrd`,这是一个 *trait*。下一部分会讲到 trait,不过简单来说,这个错误表明`largest`的函数体不能适用于`T`的所有可能的类型;因为在函数体需要比较`T`类型的值,不过它只能用于我们知道如何排序的类型。标准库中定义的`std::cmp::PartialOrd` trait 可以实现类型的排序功能。在下一部分会再次回到 trait 并讲解如何为泛型指定一个 trait,不过让我们先把这个例子放在一边并探索其他那些可以使用泛型类型参数的地方。
|
||||||
|
|
||||||
<!-- Liz: this is the reason we had the topics in the order we did in the first
|
<!-- Liz: this is the reason we had the topics in the order we did in the first
|
||||||
draft of this chapter; it's hard to do anything interesting with generic types
|
draft of this chapter; it's hard to do anything interesting with generic types
|
||||||
@ -149,7 +149,7 @@ values of type `T`</span>
|
|||||||
|
|
||||||
其语法类似于函数定义中的泛型应用。首先,必须在结构体名称后面的尖括号中声明泛型参数的名称。接着在结构体定义中可以指定具体数据类型的位置使用泛型类型。
|
其语法类似于函数定义中的泛型应用。首先,必须在结构体名称后面的尖括号中声明泛型参数的名称。接着在结构体定义中可以指定具体数据类型的位置使用泛型类型。
|
||||||
|
|
||||||
注意`Point`的定义中是使用了要给泛型类型,我们想要表达的是结构体`Point`对于一些类型`T`是泛型的,而且字段`x`和`y`**都是**相同类型的,无论它具体是何类型。如果尝试创建一个有不同类型值的`Point`的实例,像列表 10-7 中的代码就不能编译:
|
注意`Point`的定义中只使用了一个泛型类型,我们想要表达的是结构体`Point`对于一些类型`T`是泛型的,而且字段`x`和`y`**都是**相同类型的,无论它具体是何类型。如果尝试创建一个有不同类型值的`Point`的实例,像列表 10-7 中的代码就不能编译:
|
||||||
|
|
||||||
<span class="filename">Filename: src/main.rs</span>
|
<span class="filename">Filename: src/main.rs</span>
|
||||||
|
|
||||||
@ -336,4 +336,4 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
我们可以使用泛型来编写不重复的代码,而 Rust 会将会为每一个实例编译其特定类型的代码。这意味着在使用泛型时没有运行时开销;当代码运行,它的执行效率就跟好像手写每个具体定义的重复代码一样。这个单态化过程正是 Rust 泛型在运行时极其高效的原因。
|
我们可以使用泛型来编写不重复的代码,而 Rust 将会为每一个实例编译其特定类型的代码。这意味着在使用泛型时没有运行时开销;当代码运行,它的执行效率就跟好像手写每个具体定义的重复代码一样。这个单态化过程正是 Rust 泛型在运行时极其高效的原因。
|
@ -4,7 +4,7 @@
|
|||||||
> <br>
|
> <br>
|
||||||
> commit c49e5ee8859f8eb8f8867cbeafbdf5b802aa5894
|
> commit c49e5ee8859f8eb8f8867cbeafbdf5b802aa5894
|
||||||
|
|
||||||
当在第四章讨论引用时,我们遗漏了一个重要的细节:Rust 中的每一个引用都有其**生命周期**,也就是引用保持有效的作用域。大部分时候生命周期是隐含并可以推断的,正如大部分时候类型也是可以推断的一样。类似于当因为有多种可能类型的时候必须注明类型,也会出现引用的生命周期以多种不同方式向关联的情况,所以 Rust 需要我们使用泛型生命周期参数来注明他们的关系,这样就能确保运行时实际使用的引用绝对是有效的。
|
当在第四章讨论引用时,我们遗漏了一个重要的细节:Rust 中的每一个引用都有其**生命周期**,也就是引用保持有效的作用域。大部分时候生命周期是隐含并可以推断的,正如大部分时候类型也是可以推断的一样。类似于当因为有多种可能类型的时候必须注明类型,也会出现引用的生命周期以多种不同方式相关联的情况,所以 Rust 需要我们使用泛型生命周期参数来注明他们的关系,这样就能确保运行时实际使用的引用绝对是有效的。
|
||||||
|
|
||||||
好吧,这有点不太寻常,而且也不同于其他语言中使用的工具。生命周期,从某种意义上说,是 Rust 最与众不同的功能。
|
好吧,这有点不太寻常,而且也不同于其他语言中使用的工具。生命周期,从某种意义上说,是 Rust 最与众不同的功能。
|
||||||
|
|
||||||
@ -458,7 +458,7 @@ methods. /Carol -->
|
|||||||
|
|
||||||
当为带有生命周期的结构体实现方法时,其语法依然类似列表 10-10 中展示的泛型类型参数的语法:包括声明生命周期参数的位置和生命周期参数是否与结构体字段或方法的参数与返回值相关联。
|
当为带有生命周期的结构体实现方法时,其语法依然类似列表 10-10 中展示的泛型类型参数的语法:包括声明生命周期参数的位置和生命周期参数是否与结构体字段或方法的参数与返回值相关联。
|
||||||
|
|
||||||
(实现方法时)结构体字段的生命周期必须总是在`impl`关键字之后声明并在结构体名称之后被适用,因为这些生命周期是结构体类型的一部分。
|
(实现方法时)结构体字段的生命周期必须总是在`impl`关键字之后声明并在结构体名称之后被使用,因为这些生命周期是结构体类型的一部分。
|
||||||
|
|
||||||
`impl`块里的方法签名中,引用可能与结构体字段中的引用相关联,也可能是独立的。另外,生命周期省略规则也经常让我们无需在方法签名中使用生命周期注解。让我们看看一些使用列表 10-24 中定义的结构体`ImportantExcerpt`的例子。
|
`impl`块里的方法签名中,引用可能与结构体字段中的引用相关联,也可能是独立的。另外,生命周期省略规则也经常让我们无需在方法签名中使用生命周期注解。让我们看看一些使用列表 10-24 中定义的结构体`ImportantExcerpt`的例子。
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user