< 返回版块

Grobycn 发表于 2021-05-21 15:57

例如下面这段伪代码

struct Parent {
    Child1* child1;
    Child2* child2;
}

struct Child1 {
    Parent* parent;

    void do_something() {
        if (some_condition) {
            parent.child2.do_something();
        }
    }
}

struct Child2 {
    Parent* parent;

    void do_something();
}

评论区

写评论
作者 Grobycn 2021-05-23 19:40

谢谢。

--
👇
pynixwang: ``` struct Parent { Child1* child1; Child2* child2; void do_something(){ child1.do_something() child2.do_something() }

}

struct Child1 {

void do_something();

}

struct Child2 {

void do_something();

}


把组合逻辑移动到组合字段的地方。算是单一职责原则吧。
pynixwang 2021-05-22 19:28
struct Parent {
    Child1* child1;
    Child2* child2;
    void do_something(){
        child1.do_something()
        child2.do_something()
    }

}

struct Child1 {

    void do_something();
}

struct Child2 {

    void do_something();
}

把组合逻辑移动到组合字段的地方。算是单一职责原则吧。

作者 Grobycn 2021-05-21 20:12

调用的方法需要修改自己,以及其它的部分。所以需要 &mut self

--
👇
leslieDD: 这样算不算:

use std::cell::RefCell;
use std::rc::{Rc, Weak};

struct Child {
    name: String,
    parent: RefCell<Vec<Weak<Parent>>>,
}

impl Child {
    fn show(&self) {
        for v in self.parent.borrow().iter() {
            println!(
                "hi, {}, my name is {}",
                v.upgrade().unwrap().show(),
                self.name
            )
        }
    }
}

struct Parent {
    name: String,
    child: Rc<Child>,
}

impl Parent {
    fn show(&self) -> String {
        self.name.clone()
    }
}

pub fn thismod() {
    let child: Rc<Child> = Rc::new(Child {
        name: "diandian".to_string(),
        parent: RefCell::new(vec![]),
    });
    let p = Rc::new(Parent {
        name: "father".to_string(),
        child: Rc::clone(&child),
    });

    let mut parent = child.parent.borrow_mut();
    parent.push(Rc::downgrade(&p));
    drop(parent);
    child.show();
}

运行结果:

PS D:\rust\yb> cargo run
   Compiling yb v0.1.0 (D:\rust\yb)
    Finished dev [unoptimized + debuginfo] target(s) in 1.20s
     Running `target\debug\yb.exe`
hi, father, my name is diandian
PS D:\rust\yb> 
作者 Grobycn 2021-05-21 20:10

我其实是想问 rust 下,有没有 idiomatic 的设计模式可以避免使用 相互引用。

--
👇
viruscamp: 这是自引用结构哦, 基本上 unsafe 才可以创建, 你还要 Pin 住它.
safe 的情况下, 创建 Rc<RefCell<Parent>> 或者 Arc<Mutex<Parent>> , 然后内部的 Parent 指针要用 Option<Weak<Parent>> .

leslieDD 2021-05-21 19:01

这样算不算:

use std::cell::RefCell;
use std::rc::{Rc, Weak};

struct Child {
    name: String,
    parent: RefCell<Vec<Weak<Parent>>>,
}

impl Child {
    fn show(&self) {
        for v in self.parent.borrow().iter() {
            println!(
                "hi, {}, my name is {}",
                v.upgrade().unwrap().show(),
                self.name
            )
        }
    }
}

struct Parent {
    name: String,
    child: Rc<Child>,
}

impl Parent {
    fn show(&self) -> String {
        self.name.clone()
    }
}

pub fn thismod() {
    let child: Rc<Child> = Rc::new(Child {
        name: "diandian".to_string(),
        parent: RefCell::new(vec![]),
    });
    let p = Rc::new(Parent {
        name: "father".to_string(),
        child: Rc::clone(&child),
    });

    let mut parent = child.parent.borrow_mut();
    parent.push(Rc::downgrade(&p));
    drop(parent);
    child.show();
}

运行结果:

PS D:\rust\yb> cargo run
   Compiling yb v0.1.0 (D:\rust\yb)
    Finished dev [unoptimized + debuginfo] target(s) in 1.20s
     Running `target\debug\yb.exe`
hi, father, my name is diandian
PS D:\rust\yb> 
viruscamp 2021-05-21 16:18

这是自引用结构哦, 基本上 unsafe 才可以创建, 你还要 Pin 住它.
safe 的情况下, 创建 Rc<RefCell<Parent>> 或者 Arc<Mutex<Parent>> , 然后内部的 Parent 指针要用 Option<Weak<Parent>> .

1 共 6 条评论, 1 页