Hello,
In an application I'm developing, I have a recursive enum, with the child of each enum "node" being wrapped in an Arc. To parse that enum, I "peel" it, removing the layers of an enum - so:
TheEnum {
Arc {
TheEnum {
Arc {
TheEnum {
data : 20,
}
}
}
}
}
would become (after 1 "peeling"):
TheEnum {
Arc {
TheEnum {
data : 20,
}
}
}
Obviously, the above is an extreme simplification of what I'm doing - TheEnum contains more information than just the arc of it's child. Apparently Box does not work (I'll try again, but I don't think it does, I've tried it before). However, I have to "peel" the enum to different levels many times (for example, if the user inputs "2", the outer 2 layers are removed, if the user inputs 3, the outer 3 are removed, etc). Repeatedly peeling to different degrees requires that you reset the enum that you're going to peel back to the original (if you've already peeled the enum 3 times and the user requests it peeled only 2 times, you're screwed, because each "peeling" already removes the information in the enum above it). However, trying to clone() the enum only increases the refcount, which then makes the try_unwrap function for Arc fail. Any ideas on how to deep clone a recursive enum containing an Arc?
If the above was confusing, yeah, it is, I couldn't find a good way to explain it. If you're confused just ask, I'll do my best to answer.
Or even better, is there a way to avoid cloneing the structure in the first place (for example, "peel" the enum without actually making any modifications to the original enum)?
Rust's Clone is generally shallow, but it depends on data types. Clone of Arc only increases refcount. Clone of enum runs (shallow) clone on its content.
Yes, if you dereference a Box you get the value in the Box.
fn main() {
struct Foo;
let boxed_thing = Box::new(Foo);
let unboxed_thing: Foo = *boxed_thing; // type annotation is not necessary
println!("{}", unboxed_thing);
}
Using "box" is going along quite well right now, however, there's one issue - is there an equivalent to a Weak pointer for Box? Right now I'm just returning a reference to the Box (I used to return a weak pointer to the arc), which is causing lifetime issues.
Wow, it's amazing how many errors occur if you switch from Arc to Box (at NO POINT does any Arc I use have more than 1 strong reference, yet it is NOT going smootly)
I wonder why do you place so much importance on keeping refcount == 1. Bumping of refcount is quite cheap — very likely much much cheaper than full clones of the content. There's no extra cost to having higher refcount. Arc doesn't even have into_inner(), so it shouldn't make any difference to you.
And there's no weak pointer for Box. If you need backreferences, then you'll need Arc. Box can be referenced with regular Rust references, but these are strictly "strong".