Rust 使用Rc<;将同一对象添加到包含两个不同对象的字段中;RefCell<;T>&燃气轮机;

Rust 使用Rc<;将同一对象添加到包含两个不同对象的字段中;RefCell<;T>&燃气轮机;,rust,move,ownership,Rust,Move,Ownership,您可以运行下面的代码 在满足以下条件时,我无法修复错误: 加上孩子现在在一只乌龟,我原来的,而不是钢筋混凝土 品种仍然有2个海龟或&海龟参数,并调用add_child添加到t1和t2 不再需要使用大量新变量两次调用海龟构造函数 Rc-RefCell范式仍在使用 条件3很重要,因为我从Turtle中漏掉了一堆字段,如果我将它们重新添加并保留s和t的声明,将会有大量重复的代码。所以问题是,我如何用一个大的统一变量来替换s和t,这个变量可以被传递给add_child并用于breed函数的返回值

您可以运行下面的代码

在满足以下条件时,我无法修复错误:

  • 加上孩子现在在一只乌龟,我原来的,而不是钢筋混凝土

  • 品种仍然有2个海龟或&海龟参数,并调用add_child添加到t1和t2

  • 不再需要使用大量新变量两次调用海龟构造函数

  • Rc-RefCell范式仍在使用

  • 条件3很重要,因为我从Turtle中漏掉了一堆字段,如果我将它们重新添加并保留s和t的声明,将会有大量重复的代码。所以问题是,我如何用一个大的统一变量来替换s和t,这个变量可以被传递给add_child并用于breed函数的返回值,而不会导致任何移动错误?条件1对我来说并不重要,如果add_child继续需要Rc RefCell,那就这样吧。条件4非常重要,因为它意味着我的代码的其余部分,一旦我将其添加回,将顺利运行。注意,如果需要的话,品种的参数可以更改为&海龟,尽管我认为这是不必要的

    更新:我决定让函数返回一个&Turtle,但它仍然不起作用

    pub fn breed<'a>(t1: &'a mut Turtle, t2: &'a mut Turtle, name: String) -> &'a Turtle{
        let s = Rc::new(RefCell::new(Turtle {name: name, children:Vec::new()}));
        t1.add_child(Rc::clone(&s));
        t2.add_child(Rc::clone(&s));
        &*s.borrow_mut()
    }
    
    我现在该怎么办?我已经用尽了函数返回的所有选项,知道它必须是&海龟,并且它必须指向与s相同的海龟。换句话说,如果t1或t2修改了一个子对象,那么同样的修改也必须应用于返回的海龟

    更新2:我需要返回一个Turtle或&Turtle的原因是因为我在另一个类中使用了结果,如下面的函数所示

    pub fn breed_turtles(&mut self, t1_index: usize, t2_index: usize, child_name: String) {
        let n = self.size();
        if t1_index>n-1 || t2_index>n-1 {
            panic!("out of bounds");
        }
        let t = Turtle::breed(&mut self.turtles[t1_index].t.borrow_mut(),&mut self.turtles[t2_index].t.borrow_mut(),child_name);
        self.add_turtle(*t);
    }
    

    我遵循Lagerbear的建议,创建了繁殖返回s,创建了一个add_-turtle_-ref函数,该函数在繁殖海龟中使用TurtleRef={t:Rc},并最终用add_-turtle_-ref实现了add_-turtle。但是,add_-turtle_-ref有一个错误,传奇还在继续。

    正如错误所述,您正在尝试移动字符串。你可以克隆它。你也可以把它变成一个
    &str
    ,它只是一个引用,因此可以在没有分配开销的情况下进行复制,但这会带来生命周期的复杂性;一个是您正在返回的,另一个是属于
    Rc
    的。他们不能同时拥有同一个字符串。@皮特将检查我的更新。我同意他们拥有相同的字符串,因为我同意在t1或t2修改其子对象时修改返回的海龟。事实上,这正是我想要发生的。“我对它们拥有相同的字符串很好,因为我对返回的海龟在t1或t2修改其子对象时被修改很好。”也许你对此没意见;但是锈作为一种语言是专门设计的,不适合这种情况您不能在函数中返回
    s
    ?不是借钱,而是实际归还?就风格而言,这有点不确定;通常情况下,让函数返回某些内容或执行某些副作用操作会更干净。在您的例子中,它向输入海龟添加一个子海龟并返回该子海龟。也许你真的不需要归还它?
    pub fn breed<'a>(t1: &'a mut Turtle, t2: &'a mut Turtle, name: String) -> &'a Turtle{
        let s = Rc::new(RefCell::new(Turtle {name: name, children:Vec::new()}));
        t1.add_child(Rc::clone(&s));
        t2.add_child(Rc::clone(&s));
        &*s.borrow_mut()
    }
    
    error[E0515]: cannot return value referencing local variable `s`
      --> src/lib.rs:20:9
       |
    20 |         &*s.borrow_mut()
       |         ^^-^^^^^^^^^^^^^
       |         | |
       |         | `s` is borrowed here
       |         returns a value referencing data owned by the current function
    
    error[E0515]: cannot return value referencing temporary value
      --> src/lib.rs:20:9
       |
    20 |         &*s.borrow_mut()
       |         ^^--------------
       |         | |
       |         | temporary value created here
       |         returns a value referencing data owned by the current function
    
    pub fn breed_turtles(&mut self, t1_index: usize, t2_index: usize, child_name: String) {
        let n = self.size();
        if t1_index>n-1 || t2_index>n-1 {
            panic!("out of bounds");
        }
        let t = Turtle::breed(&mut self.turtles[t1_index].t.borrow_mut(),&mut self.turtles[t2_index].t.borrow_mut(),child_name);
        self.add_turtle(*t);
    }