mirror of
https://github.com/gnu4cn/rust-lang-zh_CN.git
synced 2025-01-30 14:10:13 +08:00
Improve Ch13
This commit is contained in:
parent
6ec8630461
commit
c9782e2241
@ -319,15 +319,15 @@ impl<T> Option<T> {
|
||||
}
|
||||
```
|
||||
|
||||
回顾到 `T` 就是表示 `Optoin` 的 `Some` 变种中,值类型的泛型。类型 `T` 也是 `unwrap_or_else` 函数的返回值类型:比如,在 `Option<String>` 上调用 `unwrap_or_else` 的代码,就会得到一个 `String`。
|
||||
回顾到 `T` 就是表示 `Optoin` 的 `Some` 变种中,值类型的泛型。类型 `T` 也是 `unwrap_or_else` 函数的返回值类型:比如,在 `Option<String>` 上调用 `unwrap_or_else` 的代码,就将得到一个 `String`。
|
||||
|
||||
接着,请注意这个 `unwrap_or_else` 函数有个额外的泛型参数 `F`。这个 `F` 类型为名为 `f` 的参数类型,而这个参数 `f`,则正是在调用 `unwrap_or_else` 时,所提供到的那个闭包。
|
||||
接下来,请留意 `unwrap_or_else` 函数有个额外的泛型参数 `F`。`F` 类型是名为 `f` 的参数类型,其正是调用 `unwrap_or_else` 时,咱们提供的闭包。
|
||||
|
||||
在这个泛型 `F` 上所指定的特质边界(the trait bound),为 `FnOnce() -> T`,就表示 `F` 必须能被调用一次、不取参数,并要返回一个 `T` 类型值。在特质边界中使用 `FnOnce`,表示 `unwrap_or_else` 只会调用 `f` 至多一次这样的约束。而在 `unwrap_or_else` 的函数体中,就可以看到在那个 `Option` 为 `Some` 时,`f` 不会被调用。在 `Option` 为 `None` 时,`f` 就会被调用一次。由于所有闭包都实现了 `FnOnce`,因此 `unwrap_or_else` 就会接收最为广泛的闭包,进而有着其最大的灵活性。
|
||||
泛型 `F` 上所指定的特质边界,the trait bound,为 `FnOnce() -> T`,表示 `F` 必须能被调用一次、不取参数,并要返回 `T` 类型值。在特质边界中使用 `FnOnce`,表示 `unwrap_or_else` 只会调用 `f` 最多一次的约束。在 `unwrap_or_else` 的主体中,咱们就可以看到,当 `Option` 为 `Some` 时,`f` 不会被调用。当 `Option` 为 `None` 时,`f` 就会被调用一次。由于所有闭包都实现了 `FnOnce`,`unwrap_or_else` 会接收最为广泛的闭包,而尽可能地灵活。
|
||||
|
||||
> **注意**:函数也可以实现全部三个 `Fn` 特质。在打算执行的操作,不需要捕获环境中某个值时,就可以在需要某个实现了 `Fn` 特质处,使用某个函数名字而非闭包。比如,在某个 `Option<Vec<T>>` 值上,若这个值为 `None`,那么就可以调用 `unwrap_or_else(Vec::new)` 来获取到一个新的空矢量值。
|
||||
> 注意:函数也可实现全部三个 `Fn` 特质。当咱们打算执行的操作,不需要捕获环境中的值时,便可在需要实现了 `Fn` 特质的物件处,使用函数名字而非闭包。比如,在 `Option<Vec<T>>` 值上,若该值为 `None`,那么咱们就可以调用 `unwrap_or_else(Vec::new)` 来获取到一个新的空矢量值。
|
||||
|
||||
现在来检视一下定义在切片上的那个标准库方法 `sort_by_key`,来看看其与 `unwrap_or_else` 有何区别,以及为何 `sort_by_key` 会使用 `FnMut` 而非 `FnOnce` 作为特质边界。其中的闭包,获得的是一个到正被处理切片中当前元素的引用形式的参数,并返回一个可被排序类型 `K` 的一个值。在想要以各个条目的某种特定属性,对切片进行排序时,此函数是有用的。在下面清单 13-7 中,就有一个 `Rectangle` 实例的清单,进而这里使用了 `sort_by_key`,来以 `width` 属性的升序对这些 `Rectangle` 实例加以排序:
|
||||
现在咱们来看看定义在切片上的标准库方法 `sort_by_key`,以看出其与 `unwrap_or_else` 有何区别,及为何 `sort_by_key` 会使用 `FnMut` 而非 `FnOnce` 作为特质边界。闭包会得到一个到正被处理切片中,当前元素引用形式的参数,并返回可被排序的类型 `K` 的值。在咱们想要以各个条目的某种特定属性,对切片进行排序时,这个函数是有用的。在下面清单 13-7 中,咱们有着一个 `Rectangle` 实例的清单,且咱们使用了 `sort_by_key`,来以 `width` 属性的升序,对 `Rectangle` 实例加以排序:
|
||||
|
||||
文件名:`src/main.rs`
|
||||
|
||||
@ -395,7 +395,7 @@ $ cargo run
|
||||
]
|
||||
```
|
||||
|
||||
`sort_by_key` 之所以被定义为取一个 `FnMut` 闭包,是由于他多次调用了这个闭包:对那个切片中的每个条目运行一次。那个闭包 `|r| r.width` 并不会捕获、修改,或是从其环境迁移任何东西,因此他就满足了 `FnMut` 这个特质边界的那些要求。
|
||||
`sort_by_key` 被定义为取 `FnMut` 闭包的原因是,他会多次调用闭包:对切片中的每个条目调用一次。闭包 `|r| r.width` 不会捕获、修改,或从其环境迁迁出任何东西,因此其满足特质边界要求。
|
||||
|
||||
作为对照,下面清单 13-8 给出一个仅实现了 `FnOnce` 特质的闭包示例,正是因为该闭包将值迁移出了其环境。编译器不会允许咱们在 `sort_by_key` 下使用这个闭包:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user