Eloff
Eloff

Reputation: 21656

How to return a reference to something inside a moved box?

I want to store a Box in a map, and take the address of the contents of the Box and hand it out to C code. This is why I don't just store the value directly in the map, as map values move when a map grows.

I'd like a function that returns a reference to the contents of the Box, that I can use in Rust code and either use as-is in Rust code, or convert the returned reference to a raw pointer for C.

This code illustrates what I'm trying to do, but it doesn't work for obvious reasons. However, it's not clear to me how to fix it.

use std::collections::{HashMap};

fn box_and_ref<'a>(map: &'a mut HashMap<String, Box<Vec<u8>>>) -> &'a Vec<u8> {
    let v = vec!{b'h', b'e', b'l', b'l', b'o'};
    let b = Box::new(v);
    let r = b.as_ref();
    map.insert("foo".to_string(), b);
    r
}

fn main() {
    let mut map: HashMap<String, Box<Vec<u8>>> = HashMap::new();

    let v = box_and_ref(&mut map);
    println!("{:?}", v);
}

playground link

Upvotes: 0

Views: 915

Answers (1)

mcarton
mcarton

Reputation: 29981

For any “avoid double lookup” issues, use the entry API:

fn box_and_ref<'a>(map: &'a mut HashMap<String, Box<Vec<u8>>>) -> &'a Vec<u8> {
    let v = vec!{b'h', b'e', b'l', b'l', b'o'};
    let b = Box::new(v);
    map.entry("foo".to_string()).or_insert(b)
}

Upvotes: 2

Related Questions