作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定类型为Vec<&'static str>
的值,我可以自由地将其转换为Vec<&'r str>
,因为'r
是'static
的子区域。这似乎适用于大多数类型,例如Vec
,pairs等。但是,它不适用于Cell
或RefCell
之类的类型。具体来说,down_vec
会编译,但是down_cell
不会:
use std::cell::Cell;
fn down_vec<'p, 'r>(x: &'p Vec<&'static str>) -> &'p Vec<&'r str> {
x
}
fn down_cell<'p, 'r>(x: &'p Cell<&'static str>) -> &'p Cell<&'r str> {
x
}
error[E0308]: mismatched types
--> src/lib.rs:9:5
|
9 | x
| ^ lifetime mismatch
|
= note: expected reference `&'p std::cell::Cell<&'r str>`
found reference `&'p std::cell::Cell<&'static str>`
note: the lifetime `'r` as defined on the function body at 8:18...
--> src/lib.rs:8:18
|
8 | fn down_cell<'p, 'r>(x: &'p Cell<&'static str>) -> &'p Cell<&'r str> {
| ^^
= note: ...does not necessarily outlive the static lifetime
Cell
不起作用?编译器如何跟踪它不起作用?是否有其他方法可以使其正常工作?
最佳答案
Cell
和RefCell
不同,因为它们允许通过共享引用对内部值进行突变。
要了解为什么这很重要,我们可以编写一个函数,使用down_cell
泄漏对释放内存的引用:
fn oops() -> &'static str {
let cell = Cell::new("this string doesn't matter");
let local = String::from("this string is local to oops");
let broken = down_cell(&cell); // use our broken function to rescope the Cell
broken.set(&local); // use the rescoped Cell to mutate `cell`
cell.into_inner() // return a reference to `local`
} // uh-oh! `local` is dropped here
oops
不包含
unsafe
块,但可以编译,因此为了防止访问释放的内存,编译器必须拒绝
down_cell
。
Cell<T>
和
RefCell<T>
包含
UnsafeCell<T>
,这使它们在
T
中不变,而
Box<T>
和
Vec<T>
在
T
中是协变的。
Vec
,
Box
和其他类似容器的结构之所以可以协变的原因是因为这些容器需要
&mut
访问权才能对其内容进行变异,而
&mut T
本身在
T
中是不变的。您无法使用
oops
编写类似于
down_vec
的函数-编译器不允许这样做。
关于rust - Rust生命周期子类型不适用于Cell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62085032/
我正在开发一个使用多个 turtle 的滚动游戏。玩家 turtle 根据按键命令在 Y 轴上移动。当危害和好处在 X 轴上移动时,然后循环并改变 Y 轴位置。我尝试定义一个名为 colliding(
我不明白为什么他们不接受这个作为解决方案,他们说这是一个错误的答案:- #include int main(void) { int val=0; printf("Input:- \n
我正在使用基于表单的身份验证。 我有一个注销链接,如下所示: 以及对应的注销方法: public String logout() { FacesContext.getCurren
在 IIS7 应用程序池中有一个设置 Idle-time out 默认是 20 分钟,其中说: Amount of time(in minutes) a worker process will rem
我是一名优秀的程序员,十分优秀!