前言
本系列文章为介绍Rust更新的各版本特性。从当前版本开始往后更新。
本期内容是Rust 1.65.0
的新版本特新,包括
- 泛型关联类型
- let-else语句
- break标记语法
等内容,当然本次更新还有一个特性,就是差分Linux调试信息
,由于我目前还是在Windows环境下进行编程,就不写这部分内容了,如果你感兴趣,可以去更新文档研究研究。
更新Rust
如果你还没有更新rust,那么就运行以下命令来更新你的rust。
如果你的版本是nightly,那么请运行以下命令进行更新
如果你的版本是beta版本,请运行以下命令进行更新
高于此版本不用更新
一、泛型关联类型
现在可以在关联类型上定义生存期、类型和常量泛型,如下所示:
1 2 3
| trait Foo { type Bar<'x>; }
|
类似生成器的trait,可以从Self借用泛型关联类型
1 2 3 4 5
| trait LendingIterator { type Item<'a> where Self: 'a;
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>; }
|
可以在智能指针(如“Rc”或“Arc”)上实现,以便允许在指针类型上使用泛型
1 2 3 4 5
| trait PointerFamily { type Pointer<T>: Deref<Target = T>;
fn new<T>(value: T) -> Self::Pointer<T>; }
|
允许借用数组。对于类似“NdArray”的类型非常有用,这些类型不必连续存储数据。
1 2 3 4 5
| 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>; }
|
二、let-else语句
let-else语法格式
1 2 3
| let PATTERN: TYPE = EXPRESSION else { DIVERGING_CODE; };
|
note:
PATTERN
:变量名
TYPE
:类型
EXPRESSION
:表达式
DIVERGING_CODE
:代码
正常的语句只能使用静态的、已知的模式来匹配返回的结构、元组等,现在可以在模式不匹配时进行处理
1 2 3 4 5 6 7 8 9 10 11
| 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"));
|
名称绑定的范围是区别于match或if-let-else表达式的主要原因
1 2 3 4 5 6 7 8 9
| 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标记语法
在很多常规代码中,你可能见过使用了一个循环,仅仅是为了获取一个标记,这就使得代码变得很复杂。Rust专门针对这个问题退出了一个语言功能,标记也可以包含一个表达式值,就像循环一样,让多语句块可以提前返回
值。
1 2 3 4 5 6 7 8 9 10 11 12
| 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 };
|
在之前的Rust中,是支持break指定标记的,用来消除循环中的歧义,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| fn main() { let mut count = 0; 'counting_up: loop { println!("count = {count}"); let mut remaining = 10;
loop { println!("remaining = {remaining}"); if remaining == 9 { break; } if count == 2 { break 'counting_up; } remaining -= 1; }
count += 1; } println!("End count = {count}"); }
|
通过有标记的break可以很轻松的消除break在代码中的歧义,否则break的时候就要靠程序员的经验了。
总结
以上内容就是Rust 1.65.0更新的主要内容了,很明显我也是一知半解,所以在这里占个坑,这些知识在用的时候才会起到作用。