Rust

关于Rust中常见的生命期的“例子”(一)

2022-03-30  本文已影响0人  神奇的考拉

一、说明

类型 含义 样例
T 1、所有可能的类型集合或其中一个具体类型 T,&T,&&T;i32,&i32,&&i32
&T T类型的引用(共享不可变的引用) &i32, &&i32
&mut T T类型的可变引用(独占可变引用) &mut i32

T类型是&T和&mut T的超集;

“可变不共享,共享不可变”

在Rust中一个变量的生命期是指其所指向的内存地址中数据有效的“一段时期”;而这段时期是有编译器静态分析得出的,有效性是由编译器保证的

二、样例

1、T 只包含所有权类型

类型 T &T &mut T
样例 i32 &i32 &mut i32

其中T包含全体所有权类型;&T包括全体不可变引用;&mut T包括全体可变引用;
其中T、&T、&mut T是不相交的有限集合

实际情况如下

类型 T &T &mut T
例子 i32,&i32,&muti32,&&i32,&mut &mut i32,... &i32,&&i32,&&mut i32,... &mut i32, &mut &mut i32, &mut &i32,...

T, &T, &mut T都是无限集合; T是&T和&mut T的超集(由于可引用类型T自身无限次),且&T和&mut T是不相交的集合

trait TestTrait {}


impl<T> TestTrait for T {}      // target-1


impl<T> TestTrait for &T {}     // target-2


impl<T> TestTrait for &mut T {} // target-3

上述代码是不能编译通过的:

error[E0119]: conflicting implementations of trait `TestTrait` for type `&_`
 --> src/bin/trait_generic_demo.rs:6:1
  |
4 | impl <T> TestTrait for T{}
  | ------------------------ first implementation here
5 | 
6 | impl<T> TestTrait for &T {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`

所以验证了“T是&T和&mut T的超集”,也就意味着“target-1”的代码包括了“target-2”和“target-3”的实现;
而若是注释掉“target-1”的代码,其他不变,则编译也是OK的,说明了“&T和&mut T是不相交的集合”

2、若是 T:'static,那么T的生命周期就会直到程序结束为止都一定是有效的

let str_literal: &'static str = "字符串字面量";

这里的“字符串字面量”会被硬编码到编译出来的二进制文件中,并在运行时被加载到只读内存中,在整个运行期间有效且不可变的,使其生命周期为'static。 ???

举个例子:

static strs: [&str; 3] = ["hello", "world", "yes"];
static mut mut_strs: [&str; 3] = ["hello", "world", "yes"];

fn main() {
    // 错误信息
    // error[E0594]: cannot assign to `strs[_]`, as `strs` is an immutable static item
    //  --> src/bin/static_var_demo.rs:7:5
    //   |
    // 7 |     strs[0] = "come_here";
    //   |     ^^^^^^^^^^^^^^^^^^^^^ cannot assign
    // strs[0] = "come_here";
    unsafe {
        mut_strs[0] = "come_here";
        assert_eq!("come_here", mut_strs[0]);
    }
}

从上面的示例中,得出关于静态变量

区分&'static T和 T: 'static:

use rand;

/// &'static T 样例
fn  rand_str_generator() -> &'static str {
    let rand_str = rand::random::<u64>().to_string();
    Box::leak(rand_str.into_boxed_str()); // 存在“内存泄漏”
}

/// T: 'static样例
fn drop_static<T: 'static>(t: T) {
    std::mem::drop(t);
}

fn drop_static_demo() {
    let mut strings: Vec<String> = Vec::new();
    for _ in 0..10 {
        if rand::random() {
            let string = rand::random::<u64>().to_string();
            strings.push(string);
        }
    }

    for mut string in strings {
        string.push_str(" a mutation");
        println!("{:?}", string);
        drop_static(string);
    }

    println!("i am the end of the program");
}

fn main() {
   // &'static T
   let rand_str = rand_str_generator();
    println!("{:?}", rand_str);
    // T: 'static 样例
    drop_static_demo();
}

关键点:

(待续)

上一篇 下一篇

猜你喜欢

热点阅读