如果可能的话,我想将一个结构移到另一个结构中,并在不克隆或复制的情况下,将第一结构的一部分作为其他结构的一部分获得引用。如何以正确的方式做到这一点?
fn main() {
let foo = Foo::new();
let bar = Bar::new(foo);
println!("{:?}", bar);
}
#[derive(Debug)]
struct Foo {
v: String,
}
impl Foo {
pub fn new() -> Self {
Foo {
v: String::from("a|b"),
}
}
pub fn get_a(&self) -> &str {
&self.v[0..1]
}
pub fn get_b(&self) -> &str {
&self.v[2..3]
}
}
#[derive(Debug)]
struct Bar<'a> {
foo: Foo,
a: &'a str,
b: &'a str,
}
impl<'a> Bar<'a> {
pub fn new(f: Foo) -> Self {
Bar::parse(f)
}
fn parse(f: Foo) -> Self {
let a = f.get_a();
let b = f.get_b();
Bar { foo: f, a, b }
}
}
我遇到一个错误:
error[E0515]: cannot return value referencing function parameter `f`
--> src/main.rs:44:9
|
41 | let a = f.get_a();
| - `f` is borrowed here
...
44 | Bar { foo: f, a, b }
| ^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
error[E0515]: cannot return value referencing function parameter `f`
--> src/main.rs:44:9
|
42 | let b = f.get_b();
| - `f` is borrowed here
43 |
44 | Bar { foo: f, a, b }
| ^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
error[E0505]: cannot move out of `f` because it is borrowed
--> src/main.rs:44:20
|
35 | impl<'a> Bar<'a> {
| -- lifetime `'a` defined here
...
41 | let a = f.get_a();
| - borrow of `f` occurs here
...
44 | Bar { foo: f, a, b }
| -----------^--------
| | |
| | move out of `f` occurs here
| returning this value requires that `f` is borrowed for `'a`
答案 0 :(得分:1)
f
返回时,参数parse
到parse
的生存期结束。较旧的Rust编译器版本返回了一条错误消息,该消息可能更有用:
error[E0597]: `f` does not live long enough
--> t.rs:41:17
|
41 | let a = f.get_a();
| ^ borrowed value does not live long enough
...
45 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 35:1...
--> t.rs:35:1
|
35 | / impl<'a> Bar<'a> {
36 | | pub fn new(f: Foo) -> Self {
37 | | Bar::parse(f)
38 | | }
... |
45 | | }
46 | | }
| |_^
我可以通过将Bar
的定义更改为以下内容来编译您的示例:
#[derive(Debug)]
struct Bar<'a> {
foo: &'a Foo,
a: &'a str,
b: &'a str,
}
,并将类型&'a Foo
的引用传递到Bar::new
和Bar::parse
。但是,尚不清楚此解决方案是否可以解决您的原始问题。如果所有权结构过于复杂,也许您需要使用Rc
。