我正在尝试使用新Pin功能。阅读此博客文章之后,我开始编写一些代码:
#![feature(pin, arbitrary_self_types)]
use std::mem::Pin;
pub struct Foo {
var: i32,
}
pub struct FooRef<'i> {
ref_var: &'i i32,
other: i32,
}
pub struct SimpleRef<'data> {
foo: Box<Foo>,
bar: Option<FooRef<'data>>,
}
impl<'data> SimpleRef<'data> {
fn new() -> SimpleRef<'data> {
SimpleRef {
foo: Box::new({ Foo { var: 42 } }),
bar: None,
}
}
fn init(mut self: Pin<SimpleRef<'data>>) {
let this: &mut SimpleRef = unsafe { Pin::get_mut(&mut self) };
let a = FooRef {
ref_var: &this.foo.var,
other: 12,
};
this.bar = Some(a);
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
但是我得到这个错误:
#![feature(pin, arbitrary_self_types)]
use std::mem::Pin;
pub struct Foo {
var: i32,
}
pub struct FooRef<'i> {
ref_var: &'i i32,
other: i32,
}
pub struct SimpleRef<'data> {
foo: Box<Foo>,
bar: Option<FooRef<'data>>,
}
impl<'data> SimpleRef<'data> {
fn new() -> SimpleRef<'data> {
SimpleRef {
foo: Box::new({ Foo { var: 42 } }),
bar: None,
}
}
fn init(mut self: Pin<SimpleRef<'data>>) {
let this: &mut SimpleRef = unsafe { Pin::get_mut(&mut self) };
let a = FooRef {
ref_var: &this.foo.var,
other: 12,
};
this.bar = Some(a);
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
我的代码与博客文章中的代码之间的区别在于,我使用的是带有生命周期参数的变量,而不是原始指针。
是否可以将带有生命周期参数的变量与一起使用Pin?
是否可以将带有生命周期参数的变量与一起使用
Pin?
大概。
我的代码与博客文章中的代码之间的区别在于,我使用的是带有生命周期参数的变量,而不是原始指针。
这改变了一切:Rust语言不保证指针的有效性,但是严格保证引用的有效性。
让我们研究一下引用的生命周期问题,并查看为什么本文专门使用原始指针(和unsafe代码)来克服该问题。
的签名Pin::get_mut是:
Run Code Online (Sandbox Code Playgroud)pub unsafe fn get_mut<'b>(this: &'b mut Pin<'a, T>) -> &'b mut T
也就是说,该引用仅在对的引用有效时才Pin有效。
由于Pin通过值作为参数传递,因此将其放在函数作用域的末尾。但是,您尝试在此之后保留对它的引用。这是不安全的。
使用原始指针是可以的(未经检查),因为任何尝试使用原始指针的人都将需要使用一个unsafe块,负责确保该指针确实有效。
| 归档时间: |
|
| 查看次数: |
1235 次 |
| 最近记录: |