Common Rust Lifetime Misconceptions 常见的对 Rust 生命周期的误解
Common Rust Lifetime Misconceptions
Intro
| Phrase | Shorthand for |
|---|---|
T |
1) 所有类型的集合(包括 T, &T, &mut T) 或者 2) 改集合中的某些类型 |
| owned type | 非引用类型, e.g. i32, String, Vec, etc |
| 1) borrowed type or 2) ref type |
引用类型(可变的或不可变的), e.g. &i32, &mut i32, etc |
| 1) mut ref or 2) exclusive ref |
独占式可变引用, i.e. &mut T |
| 1) immut ref or 2) shared ref |
共享式不可变引用, i.e. &T |
误解 1) T 只包含 owned types
初学 Rust 的新手常常会理解为:
| Type Variable | T |
&T |
&mut T |
| Examples | i32 |
&i32 |
&mut i32 |
而泛型在 Rust 里实际的工作方式是:
| Type Variable | T |
&T |
&mut T |
| Examples | i32, &i32, &mut i32, &&i32, &mut &mut i32, ... |
&i32, &&i32, &&mut i32, ... |
&mut i32, &mut &mut i32, &mut &i32, ... |
fn foo<T: std::fmt::Debug>(x: T) {
println!("{:?}", x);
}
fn main() {
let mut i = 42;
foo(i);
foo(&i);
foo(&&i);
foo(&&&i);
foo(&mut i);
foo(&mut &mut i);
foo(&mut &mut &mut i);
}
上面这段代码可以工作,全部输出 42。也就是说 T 是 &T 和 &mut T 的超集
trait Trait {}
impl<T> Trait for T {}
impl<T> Trait for &T {} // ❌
impl<T> Trait for &mut T {} // ❌
这段代码不能编译通过,Trait for &T 和 Trait for &mut T 会跟前面的 Trait for T 冲突。下面这段是可以编译的
trait Trait {}
impl<T> Trait for &T {} // ✅
impl<T> Trait for &mut T {} // ✅
Trait for &T 和 Trait for &mut T 是不相交的两个集合
trait Trait{
fn foo(&self);
}
impl<T> Trait for &T {
fn foo(&self) {
println!("&T");
}
}
impl<T> Trait for &mut T {
fn foo(&self) {
println!("&mut T");
}
}
fn main() {
let mut i = &42;
i.foo();
let i = &mut i;
i.foo();
}
误解 2) 如果 T: 'static 那么 T 必须在整个程序的生命周期内都是存在的
初学者第一次接触 'static lifetime 通常是在类似下面的这种代码:
fn main() {
let str_literal: &'static str = "str literal";
}
书上一般会解释说 "字面值常量"("str literal") 是被硬编码进二进制文件中的,并在运行时被加载到只读内存区域,因此它是不可变的,并且跟进程的生命周期是同步的,所以它才是 'static。 Rust 语言用 static 关键字来定义 static 变量,进一步强化了这些概念
未完。。
+V why_null 请备注:from博客园
浙公网安备 33010602011771号