Other languages do this too, for instance in Java you can override final with reflection. I lost my mind, both good and bad, when I discovered this.
It's taken me a year to feel good about my Rust code, I'm still getting a handle on unsafe though.
By “efficient” I mean I want to split my list in two for O(1) complexity, like other programming languages do.
pub struct ListNode<T> {
data: T,
prev: Weak<RefCell<ListNode<T>>>,
next: Rc<RefCell<ListNode<T>>>,
}
The code linked above probably has bugs (for sure with singleton lists), but I hope you get the idea. It allows you to splice lists in and out in constant time.Also, the code doesn't use `unsafe`. Now, you would need to use `unsafe` somewhere to actually create a list, in order to initialize the fields (or you could change the type of `next` to be `Option<...>`). However, the use of `unsafe` would be limited to that method. This tries to get at the difference between (i) occasionally using `unsafe` and (ii) having no safety guarantees at all.
There are probably lots of other pain points that you can bring up, and I'm not trying to say this should be good enough, but I thought it might help explain what is possible.