Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

rust - Is there an idiomatic way to keep references to elements of an ever-growing container?

I'm trying to write a container for objects of type T which provides access to references &T to the stored objects (I want to avoid making copies). Since the container only ever grows during its lifetime, the lifetime of the returned references &T should be the same as for the container.

The closest I got so far was to use Box<T> objects internally in my container and use Box<T>.as_ref() to return references to these objects. Then, however, I run into the same problem as in this minimal example:

fn main() {
    let mut v = vec![Box::new(1)]; // line 1
    let x = v[0].as_ref();         // line 2: immutable borrow occurs here
    println!("x = {:?}", x);       // line 3
    v.push(Box::new(2));           // line 4: mutable borrow occurs here -> error
    println!("x = {:?}", x);       // line 5
}

I understand that it would be unsound to use x in line 5 if it had been deleted from v during the the mutable borrow. But that's not the case here, and it'll never be for my container. If there's no safe way to express this in Rust, how could I "repair" the example (without copying x)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As @ker's answer says, just because you only grow a container doesn't mean references stay valid, as the memory can be reallocated.

Another solution if you're only growing the container is to just store indices instead of references:

fn main() {
    let mut v = vec!["Foo"];    // line 1
    let x = 0;                  // line 2: just store an index.
    println!("x = {:?}", v[x]); // Use the index as needed
    v.push("bar");              // line 4: No problem, there are no references.
    println!("x = {:?}", v[x]); // line 5: use the index again.
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...