yw662
March 3, 2019, 11:45pm
1
Things like this:
struct Test<'a> {
a: Rc<String>,
b: &'a str
}
fn test(v: &str) -> Test {
let t = Rc::new(v.to_string());
Test {
a: t.clone(),
b: &t
}
}
Certainly the above code wont compile because b reference t which is local,
but It might be done like this,
#[derive(Default)]
struct Test<'a> {
a: Rc<String>,
b: &'a str,
}
fn test(v: &str) -> Test {
let t = Rc::new(v.to_string());
let te = Test::default();
te.a = t.clone();
te.b = &te.a;
te
}
But, what if te.b
does not derive Default ?
The code you provide won't compile. But I'm not clear why you would want to do this. Can you explain a bit more about your desired use case?
yw662
March 3, 2019, 11:57pm
3
Just think of a struct, where some members reference others, like
struct Foo<T> {
a: Rc<T>,
b: sth. referencing a
}
Think of construct the struct when b does not derive default, that is why I want to do this.
kornel
March 4, 2019, 12:02am
4
This is a self-referential struct, and it's not possible in Rust.
It's not safe, because the borrow checker operates on fields individually, and would allow a
to be replaced while b
points to the old value.
In general, self-referential structs are an anti-pattern in rust because moving the struct in memory would cause the references to become invalid.
Some additional reading on the topic:
The short answer is that you can't create self-referential structs without significant restrictions and challenges. However, it turns out it's rarely truly necessary, so again, I'd ask why you need a pattern like this. What problem are you trying to solve?
yw662
March 4, 2019, 12:13am
6
Thanks for that.
So I am going to find another way out.