Eloff
Eloff

Reputation: 21688

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: 934

Answers (1)

mcarton
mcarton

Reputation: 30101

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