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 &TTrait for &mut T 会跟前面的 Trait for T 冲突。下面这段是可以编译的

trait Trait {}

impl<T> Trait for &T {} // ✅

impl<T> Trait for &mut T {} // ✅

Trait for &TTrait 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 变量,进一步强化了这些概念

未完。。

posted on 2022-06-14 19:27  明天有风吹  阅读(73)  评论(0编辑  收藏  举报

导航

+V atob('d2h5X251bGw=')

请备注:from博客园