假设Manager
包含对Designer
和Programmer
的引用,但Programmer
也必须保留对Designer
的引用,为了在他们想要的时候ping他们。
问题是,通过在Designer
中同时创建Programmer
和Manager::new()
,&designer
引用的活动时间不够长,因为在以下几行中,它会在Manager
内移动。
错误为'designer' does not live long enough
。
struct Programmer<'a> {
designer: &'a Designer,
}
impl<'a> Programmer<'a> {
pub fn new(designer: &'a Designer) -> Programmer<'a> {
Programmer { designer: designer }
}
}
struct Designer {
iq: u32,
}
impl Designer {
pub fn new(iq: u32) -> Designer {
Designer { iq: iq }
}
}
struct Manager<'a> {
programmer: Programmer<'a>,
designer: Designer
}
impl<'a> Manager<'a> {
pub fn new() -> Manager<'a> {
let designer = Designer::new(42);
let programmer = Programmer::new(&designer);
Manager { designer: designer, programmer: programmer }
}
}
fn main() {
Manager::new();
}
编译失败并显示以下消息:
test.rs:29:47: 29:55 error: `designer` does not live long enough
test.rs:29 let programmer = Programmer::new(&designer);
^~~~~~~~
test.rs:27:37: 32:10 note: reference must be valid for the lifetime 'a as defined on the block at 27:36...
test.rs:27 pub fn new() -> Manager<'a> {
test.rs:28 let designer = Designer::new(42);
test.rs:29 let programmer = Programmer::new(&designer);
test.rs:30
test.rs:31 Manager { designer: designer, programmer: programmer }
test.rs:32 }
test.rs:27:37: 32:10 note: ...but borrowed value is only valid for the block at 27:36
test.rs:27 pub fn new() -> Manager<'a> {
test.rs:28 let designer = Designer::new(42);
test.rs:29 let programmer = Programmer::new(&designer);
test.rs:30
test.rs:31 Manager { designer: designer, programmer: programmer }
test.rs:32 }
如果不通过Designer
注入Manager::new(&designer)
,我该如何解决此问题?
答案 0 :(得分:2)
我想你知道你在做什么,但这似乎不是Rust最好的设计。你说Programmer
应该保留对Designer
的引用以便对它们进行ping操作,但我认为ping它们意味着以某种方式改变Designer
(例如想象一些is_pinged
} {<1}}上的}字段,您可以通过简单的引用来完成。您可以通过常规的不可变引用完成所有操作,即读取不变异变量的数据或调用方法。还有什么,只要你有这个参考,原来的Designer
就不能改变。
如果你只是想拥有一个不可变的引用,那么你可以使用Rc
类型,它提供了一个不可变的引用计数指针。
如果您想以某种方式允许Designer
向Programmer
发送消息,这可能会或可能不会触发Designer
上的突变,那么您可以尝试使用频道。每个Designer
都会存储自己的channel
,并且它可以有一个方法来克隆频道的Sender
端,以便感兴趣的Designer
进行存储和使用。