translation(appendix/rust-versions) : 1.65

pull/1135/head
EluvK 2 years ago
parent a891d12239
commit 602b4dc820

@ -344,3 +344,4 @@
- [1.62](appendix/rust-versions/1.62.md)
- [1.63](appendix/rust-versions/1.63.md)
- [1.64](appendix/rust-versions/1.64.md)
- [1.65](appendix/rust-versions/1.65.md)

@ -0,0 +1,119 @@
# Rust 新版解读 | 1.65 | 重点: 泛型关联类型,新绑定语法!
> Rust 1.65 官方 release doc: [Announcing Rust 1.65.0 | Rust Blog](https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html)
通过 [rustup](https://www.rust-lang.org/tools/install) 安装的同学可以使用以下命令升级到 1.65 版本:
```shell
$ rustup update stable
```
## 泛型关联类型 Generic associated types (GATs)
关联类型associated types里现在可以加上生命周期、类型、const泛型了类似于
```rust
trait Foo {
type Bar<'x>;
}
```
三言两语说不清这个变化的好处,看几个例子来感受一下:
```rust
/// 一个类似于 `Iterator` 的 trait ,可以借用 `Self`
trait LendingIterator {
type Item<'a> where Self: 'a;
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
}
/// 可以给智能指针类型,比如 `Rc``Arc` 实现的 trait来实现指针类型的泛用性
trait PointerFamily {
type Pointer<T>: Deref<Target = T>;
fn new<T>(value: T) -> Self::Pointer<T>;
}
/// 允许借用数组对象,对不需要连续存储数据的固定长度数组类型很有用
trait BorrowArray<T> {
type Array<'x, const N: usize> where Self: 'x;
fn borrow_array<'a, const N: usize>(&'a self) -> Self::Array<'a, N>;
}
```
泛型关联类型十分通用,能够写出许多之前无法实现的模式。更多的信息可以参考下面的链接:
* [2021/08/03/GAT稳定版本推进](https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push.html)
* [2022/10/28/GAT稳定版本发布公告](https://blog.rust-lang.org/2022/10/28/gats-stabilization.html)
第一个对上面的例子进行了更深入的讨论,第二个讨论了一些已知的局限性。
更深入的阅读可以在关联类型的 [nightly reference](https://doc.rust-lang.org/nightly/reference/items/associated-items.html#associated-types) 和 [原始 RFC](https://rust-lang.github.io/rfcs/1598-generic_associated_types.html)已经过去6.5年了!) 里找到。
## `let` - `else` 语法
新的 `let` 语法,尝试模式匹配,找不到匹配的情况下执行发散的 `else` 块。
```rust
let PATTERN: TYPE = EXPRESSION else {
DIVERGING_CODE;
};
```
常规的 `let` 语法仅能使用 `irrefutable patterns`,直译为不可反驳的模式,也就是一定要匹配上。一般情况下都是单个变量绑定,也用在解开结构体,元组,数组等复合类型上。原先并不适用条件匹配,比如从枚举里确定枚举值。直到现在我们有了 `let` - `else`。这是 `refutable pattern`,直译为可反驳的模式,能够像常规 `let` 一样匹配并绑定变量到周围范围内,在模式不匹配的时候执行发送的 `else` (可以是 `break`, `return`, `panic!`)。
```rust
fn get_count_item(s: &str) -> (u64, &str) {
let mut it = s.split(' ');
let (Some(count_str), Some(item)) = (it.next(), it.next()) else {
panic!("Can't segment count item pair: '{s}'");
};
let Ok(count) = u64::from_str(count_str) else {
panic!("Can't parse integer: '{count_str}'");
};
(count, item)
}
assert_eq!(get_count_item("3 chairs"), (3, "chairs"));
```
`if` - `else``match` 或者 `if let` 最大不一样的地方是变量绑定的范围,在此之前你需要多写一点重复的代码和一次外层的 `let` 绑定来完成:
```rust
let (count_str, item) = match (it.next(), it.next()) {
(Some(count_str), Some(item)) => (count_str, item),
_ => panic!("Can't segment count item pair: '{s}'"),
};
let count = if let Ok(count) = u64::from_str(count_str) {
count
} else {
panic!("Can't parse integer: '{count_str}'");
};
```
## `break` 跳出标记过的代码块
块表达式现在可以标记为 `break` 的目标,来达到提前终止块的目的。这听起来有点像 `goto` 语法,不过这并不是随意的跳转,只能从块里跳转到块末尾。这在之前已经可以用 `loop` 块来实现了,你可能大概率见过这种总是只执行一次的 `loop`
1.65 可以直接给块语句添加标记来提前退出了,还可以携带返回值:
```rust
let result = 'block: {
do_thing();
if condition_not_met() {
break 'block 1;
}
do_next_thing();
if condition_not_met() {
break 'block 2;
}
do_last_thing();
3
};
```
## Others
其它更新细节和稳定的API列表参考[原Blog](https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html)
Loading…
Cancel
Save