首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跟踪一个调用锈蚀方法的(子)结构

跟踪一个调用锈蚀方法的(子)结构
EN

Stack Overflow用户
提问于 2022-11-11 22:21:03
回答 1查看 60关注 0票数 1

我想为add_ten创建一个MyStruct方法,它跟踪调用它的子程序(作为引用)。

代码语言:javascript
复制
struct MyStruct<'a> {
    value: i32,
    child: Option<&'a mut MyStruct<'a>>,
}

impl MyStruct<'_> {
    fn add_ten(&mut self) -> MyStruct {
        MyStruct {
            value: self.value + 10,
            child: Some(self),
        }
    }
}

fn main() {
    let mut a = MyStruct { value: 10, child: None }; // Create some struct
    let b = a.add_ten(); // Process it and return the new struct with a ref of the child who called it
    
    println!("{}", a.value); // Be able to read the value here
    println!("{}", b.value); // and here
}

然而,我得到了这个错误:

代码语言:javascript
复制
error: lifetime may not live long enough
  --> src/main.rs:10:9
   |
9  |       fn add_ten(&mut self) -> MyStruct {
   |                  ---------
   |                  |
   |                  let's call the lifetime of this reference `'1`
   |                  has type `&mut MyStruct<'2>`
10 | /         MyStruct {
11 | |             value: self.value + 10,
12 | |             child: Some(self),
13 | |         }
   | |_________^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
   |
   = note: requirement occurs because of the type `MyStruct<'_>`, which makes the generic argument `'_` invariant
   = note: the struct `MyStruct<'a>` is invariant over the parameter `'a`
   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

我知道这是一个终生的错误,但我有点被困在这里:)我希望我所要求的是足够清楚,任何帮助都是感激的!

编辑

我想使用引用的原因,是为了能够回到孩子们并修改他们。看起来像这样:

代码语言:javascript
复制
struct MyStruct<'a> {
    value: i32,
    child: Option<&'a mut MyStruct<'a>>,
}

impl MyStruct<'_> {
    fn add_ten(&mut self) -> MyStruct {
        MyStruct {
            value: self.value + 10,
            child: Some(self),
        }
    }

    fn set_childs_to_zero(self) {
        if self.child.is_none() { return; }
        let mut child = self.child.unwrap();
        
        loop {
            child.value = 0;
            if child.child.is_none() { break; }
            child = child.child.unwrap();
        }
    }
}

fn main() {
    let mut a = MyStruct { value: 10, child: None }; // Create some struct
    let b = a.add_ten(); // Process it and return the new struct with a ref of the child who called it
    
    println!("a: {}", a.value); // 10
    println!("b: {}", b.value); // 20

    b.set_childs_to_zero();
    
    println!("a: {}", a.value); // 0
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-11 23:27:55

这可能是实现你想要的东西的一个奇怪的方法。我怀疑这是不是“正确”的方式,但希望有人能够建立起来,并提供一个更好的解决方案。

代码语言:javascript
复制
use std::rc::Rc;

struct MyStruct {
    value: i32,
    child: Option<Rc<MyStruct>>,
}

impl MyStruct {
    fn add_ten(self) -> (Rc<MyStruct>, MyStruct) {
        let s = Rc::new( self );
        (
            s.clone(),
            MyStruct {
                value: s.value + 10,
                child: Some(s),
            }
        )
    }
}

fn main() {
    let a = MyStruct { value: 10, child: None }; // Create some struct
    let (a, b) = a.add_ten(); // Process it and return the new struct with a ref of the child who called it
    
    println!("{}", a.value); // Be able to read the value here
    println!("{}", b.value); // and here
}

您正在描述的用例是构建Rc的目的--提供多个所有权。您可以在文档中阅读更多有关这方面的内容。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74408718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档