advance/circle-self-ref/self-referential #758
Replies: 48 comments 17 replies
-
|
这章看得我一脸懵逼 |
Beta Was this translation helpful? Give feedback.
-
|
头痛! |
Beta Was this translation helpful? Give feedback.
-
|
头疼 决定跳过 |
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.
-
|
配套的练习目前还没出来,配合练习还是会好很多。 |
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.
-
|
一脸懵 |
Beta Was this translation helpful? Give feedback.
-
|
麻了 |
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.
-
|
这章真麻了 |
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.
-
|
感觉在啃依托答辩。 |
Beta Was this translation helpful? Give feedback.
-
|
看来和我一样,大家都麻了 |
Beta Was this translation helpful? Give feedback.
-
|
确实想吐,所有权和借用规则带来的复杂度不是一点点 |
Beta Was this translation helpful? Give feedback.
-
|
Rust的Pin并不可怕 https://zhuanlan.zhihu.com/p/1938905968348987723 |
Beta Was this translation helpful? Give feedback.
-
|
Rust 的 Unpin Trait 也不可怕 https://mp.weixin.qq.com/s/pOcQTCW_n7ywGV0gbCretA?token=1354069031&lang=zh_CN |
Beta Was this translation helpful? Give feedback.
-
|
skip |
Beta Was this translation helpful? Give feedback.
-
|
4.5这这章套中套中套看得劝退 |
Beta Was this translation helpful? Give feedback.
-
|
妥妥的语言设计上的失败 |
Beta Was this translation helpful? Give feedback.
-
|
谈谈我的理解。 struct Person {
name: String,
slice: &str,
}
//impl//用new方法返回Person,且slice指向name
fn main(){
let a = Person::new();
let b = a;//此时Person实例被移动了//指针失效了
}2.怎么办,Rust使用Pin包装对象,使得其不被移动。 let res = Person::new();
let mut boxed = Box::pin(res);
let mut another_boxed = boxed;//Person实例不被移动,Pin指针被移动实际上,用Box直接包装也可以保障Person实例不被移动,但Pin会有额外的检查和阻止行为。
3.为了使用Pin的阻止功能,需要对象实现 struct Person {
name: String,
slice: &'static str, // 使用'static生命周期简化示例
_pin: PhantomPinned,
}
impl Person {
fn new() -> Self {
let name = String::from("Alice");
let slice_ptr: *const str = &name as &str;
// 创建结构体实例
let person = Person {
name,
slice: unsafe { &*slice_ptr }, // 创建自引用
_pin: PhantomPinned,
};
person
}
fn display(&self) {
println!("Name: {}, Slice: {}, Slice addr: {:p}, Name addr: {:p}",
self.name, self.slice, self.slice, self.name.as_str());
}
}
fn main() {
// 创建结构体实例
let mut a = Person::new();
a.display();
// 尝试移动 - 这会编译通过,因为还没有用Pin包装
let mut b: Person;
unsafe {
// 注意:这个移动会导致slice指向错误的内存!
b = mem::transmute_copy(&a);
}
println!("--- 使用Pin包装后 ---");
// 用Pin包装结构体
let mut pinned_a = Box::pin(Person::new());
// 尝试使用Pin的安全API访问数据
pinned_a.as_ref().display();
// 下面的代码会编译错误 - 这就是Pin的保护作用
// let mut another = Person::new();
// mem::swap(&mut *pinned_a, &mut another);
println!("演示完成!");
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
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