advance/circle-self-ref/self-referential #758
Replies: 39 comments 16 replies
-
这章看得我一脸懵逼 |
Beta Was this translation helpful? Give feedback.
-
无法被移动的 Pin 这里,代码中有一段注释, |
Beta Was this translation helpful? Give feedback.
-
脑壳疼, 还是学会再来吧... |
Beta Was this translation helpful? Give feedback.
-
配套的练习目前还没出来,配合练习还是会好很多。 |
Beta Was this translation helpful? Give feedback.
-
#[derive(Debug)] impl<'a> WhatAboutThis<'a> { fn main() {
}
} fn change(some_string: &mut String) { |
Beta Was this translation helpful? Give feedback.
-
pin劝退了。。。 |
Beta Was this translation helpful? Give feedback.
-
这章学得好懵逼: use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;
use std::marker::PhantomPinned;
use std::ptr;
use std::ptr::NonNull;
use std::pin::Pin;
use std::mem;
///不安全的实现
struct RefSelf1<T: Display> {
value: T,
ref_value: *const T,
}
impl<T: Display> Display for RefSelf1<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(
f,
"RefSelf1 {{ value: {:p}-{}, ref_value: {:p}-{} }}",
&self.value,
self.value,
self.ref_value,
unsafe { &*self.ref_value },
)
}
}
impl<T: Display> RefSelf1<T> {
fn new(value: T) -> Self {
let mut this = Self { value, ref_value: ptr::null() };
this.ref_value = &this.value as *const T;
this
}
}
///固定到堆上的实现
struct RefSelf2<T: Display> {
value: T,
ref_value: NonNull<T>,
_marker: PhantomPinned,
}
impl<T: Display> Display for RefSelf2<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(
f,
"RefSelf2 {{ value: {:p}-{}, ref_value: {:p}-{} }}",
&self.value,
self.value,
self.ref_value,
unsafe { self.ref_value.as_ref() },
)
}
}
impl<T: Display> RefSelf2<T> {
fn new(value: T) -> Pin<Box<Self>> {
let mut this = Box::pin(Self {
value,
ref_value: NonNull::dangling(),
_marker: PhantomPinned,
});
unsafe {
this.as_mut().get_unchecked_mut().ref_value = NonNull::from(&this.value);
}
this
}
}
fn main() {
let mut refself11 = RefSelf1::new("hello".to_owned());
println!("refself11 = {}", refself11);
let mut refself12 = RefSelf1::new("world".to_owned());
println!("refself12 = {}", refself12);
mem::swap(&mut refself11, &mut refself12);
println!("refself11 = {}", refself11);
println!("refself12 = {}", refself12);
let mut refself21 = RefSelf2::new("hello".to_owned());
println!("refself21 = {}", refself21);
let mut refself22 = RefSelf2::new("world".to_owned());
println!("refself22 = {}", refself22);
mem::swap(&mut refself21, &mut refself22);
println!("refself21 = {}", refself21);
println!("refself22 = {}", refself22);
} |
Beta Was this translation helpful? Give feedback.
-
这个问题,我觉得是rust没有构造函数导致的。因为没有构造函数,无法在结构体初始化的过程中通过self引用value给pointer_to_value赋值。所以只能想办法把pointer_to_value占个位空着,先把结构体构造出来,然后再去赋值 |
Beta Was this translation helpful? Give feedback.
-
在一个 &mut self 的方法里调用 &mut self 的方法,是不是自引用的范畴。 |
Beta Was this translation helpful? Give feedback.
-
这个是链表和树的基础呀,但是真的难 |
Beta Was this translation helpful? Give feedback.
-
fn creator<'a>() -> WhatAboutThis<'a> {
let mut tricky = WhatAboutThis {
name: "Annabelle".to_string(),
nickname: None,
};
tricky.nickname = Some(&tricky.name[..4]);
tricky
} 的解释可能有误导性;“其实从函数签名就能看出来端倪,'a 生命周期是凭空产生的!”这句话是对的,但是不是报错的直接原因,Rust不会阻止自引用类型。 事实上,name字段底层数据分配在堆上,move并不会影响reference。但是Rust并没有意识到这一点,仍然采取一种保守的假设:移动可能会使任何现存的引用失效。 |
Beta Was this translation helpful? Give feedback.
-
我选unsafe |
Beta Was this translation helpful? Give feedback.
-
说了这么多, 只证明一件事, rust解决不了自引的问题. |
Beta Was this translation helpful? Give feedback.
-
最新的推荐方法是: 不存储对name的直接引用, 可以改为在需要时动态计算昵称,即nickname不是引用, 而是方法nickname(), 在需要时实时计算出结果. |
Beta Was this translation helpful? Give feedback.
-
有可能自引用压根就不应该存在,引用了自身的字段,就意味着这个自身不能存在于栈上、只能存在于堆上,不然随随便便一个move或copy都会导致悬空指针的风险。 |
Beta Was this translation helpful? Give feedback.
-
borrow 之后 不是不能move吗?
取得 iOS 版 Outlook<https://aka.ms/o0ukef>
…________________________________
寄件者: 蒲灵 ***@***.***>
寄件日期: Sunday, June 30, 2024 8:23:03 PM
收件者: sunface/rust-course ***@***.***>
副本: Justin ***@***.***>; Comment ***@***.***>
主旨: Re: [sunface/rust-course] advance/circle-self-ref/self-referential (Discussion #758)
有可能自引用压根就不应该存在,引用了自身的字段,就意味着这个自身不能存在于栈上、只能存在于堆上,不然随随便便一个move或copy都会导致悬空指针的风险。
应该在对自身结构的特性实现里添加访问器来借助self指针实现“自引用”
―
Reply to this email directly, view it on GitHub<#758 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/A5WLHZ5FRXNMRBPQIEIRNXLZJ72CPAVCNFSM5S5EFKY2U5DIOJSWCZC7NNSXTOKENFZWG5LTONUW63SDN5WW2ZLOOQ5TSOJRGY3DANQ>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
催眠神书,真的看着看着就困了 |
Beta Was this translation helpful? Give feedback.
-
谁能用rust写dancinglinks算法绝对是高手。看看这个,new()中不能访问上下左右: #[derive(Debug)] impl Node {
} 是的,没错,我第一步就写不下去了,高手出手吧 |
Beta Was this translation helpful? Give feedback.
-
新版是不是没有这个问题了,为什么我试了一下不需要这么复杂呢? #[derive(Debug)] fn main() { /* |
Beta Was this translation helpful? Give feedback.
-
循环引用与自引用 看的有点懵 过一遍 等以后写代码出现这类问题 再回头看把 |
Beta Was this translation helpful? Give feedback.
-
这么大一坨,只能说 RUST 为了垃圾回收,让用户付出了太多 |
Beta Was this translation helpful? Give feedback.
-
advance/circle-self-ref/self-referential
https://course.rs/advance/circle-self-ref/self-referential.html
Beta Was this translation helpful? Give feedback.
All reactions