gpt4 book ai didi

rust - 当涉及原始指针时,Rust 如何推断生命周期?

转载 作者:行者123 更新时间:2023-12-05 08:35:54 26 4
gpt4 key购买 nike

struct MyCell<T> {
value: T
}

impl<T> MyCell<T> {
fn new(value: T) -> Self {
MyCell { value }
}

fn get(&self) -> &T {
&self.value
}

fn set(&self, new_value: T) {
unsafe {
*(&self.value as *const T as *mut T) = new_value;
}
}
}

fn set_to_local(cell: &MyCell<&i32>) {
let local = 100;
cell.set(&local);
}

fn main() {
let cell = MyCell::new(&10);
set_to_local(&cell);
}

调用cell.set(&local)时,假设 cell'x'&local'y , 我被告知协方差规则将改变 cell 的类型来自 &MyCell<'x, &i32>&MyCell<'y, &i32> .

不安全 block 内的赋值如何影响 set() 参数的生命周期推断? ?原始指针没有生命周期那么编译器怎么知道它应该 cellnew_value使用协方差具有相同的生命周期?

最佳答案

How does the assignment inside the unsafe block affect the lifetime inference for the parameters of set()?

它不是——而且这甚至不特定于原始指针或 unsafe .函数体从不影响函数签名的任何方面(此处不相关的 async fn 除外)。

Raw pointers does not have lifetime then how does the compiler know it should make cell and new_value have the same lifetime using covariance?

听起来您误读了一些建议。在您的代码中,Cell<T>T 中不变,但是对于一个内部可变类型来说,它必须在类型参数中是不变的(不是协变的)。在您的代码中,编译器推断 T 的协方差因为MyCell包含一个简单类型为 T 的字段.协变是大多数泛型类型的“典型”情况。

因此,您的代码是不健全的因为MyCellT 上是协变的但必须在 T 上保持不变.

您的代码不可靠,因为在 set() 的实现中,您正在创建对 T 的不可变引用, &self.value ,然后写给它的指称。这是“未定义的行为”不管你怎么做,因为创建&self.value向编译器/优化器断言指向的内存在引用被删除之前不会被修改。

如果你想重新实现标准库的Cell ,你必须像标准库那样做,使用 UnsafeCell 原始的:

pub struct Cell<T: ?Sized> {
value: UnsafeCell<T>,
}

UnsafeCell 是您选择退出 & 的方式的不变性保证:创建一个 &UnsafeCell<T> 断言 T不会变异。它在 T 中也是不变的, 这会自动使 T 中的包含类型不变.这两者在这里都是必需的。

关于rust - 当涉及原始指针时,Rust 如何推断生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71261078/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com