以下内容均摘自async-book
自引用类型问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #[derive(Debug)] struct Test { a: String, b: *const String, }
impl Test { fn new(txt: &str) -> Self { Test { a: String::from(txt), b: std::ptr::null(), } }
fn init(&mut self) { let self_ref: *const String = &self.a; self.b = self_ref; }
fn a(&self) -> &str { &self.a }
fn b(&self) -> &String { assert!(!self.b.is_null(), "Test::b called without Test::init being called first"); unsafe { &*(self.b) } } }
fn main() { let mut test1 = Test::new("test1"); test1.init(); let mut test2 = Test::new("test2"); test2.init();
println!("a: {}, b: {}", test1.a(), test1.b()); std::mem::swap(&mut test1, &mut test2); println!("a: {}, b: {}", test2.a(), test2.b());
}
|
以上代码会输出:
1 2
| a: test1, b: test1 a: test1, b: test2
|
交换前后所发生的事情:

知乎

知乎
自引用结构体的问题在于移动可能会导致引用成员变成野指针。那么解决办法也很简单,不让自引用结构体内存发生移动。这也就是Pin,中文意思是钉住,即把内存钉住,不让其发生移动。