2016-02-11 2 views
3

У меня в основном есть функция, которая создает некоторый объект, который нужно выделить в куче. То, что я хочу сделать, это вернуть из этой функции структуру, содержащую ссылку на это значение, выделенное кучей.Как я могу вернуть значение в штучной упаковке?

struct Cont<'a> { 
    pub v: &'a i32 
} 

impl<'a> Cont<'a> { 
    fn new(v: &'a i32) -> Cont { 
     Cont { 
      v: v 
     } 
    } 
} 

fn f<'a>() -> Cont<'a> { 
    let v = Box::new(6); 

    Cont::new(&v) 
} 

fn main() { 
    let c = f(); 

    println!("{}", c.v); 
} 

Я получаю error: 'v' does not live long enough.

Вы можете найти пример here.

ответ

4

Вы не можете вернуть структуру, которая содержит только заимствованный указатель на ваш объект, потому что ваш Box будет уничтожен в конце функции.

Вам необходимо передать право собственности на Box из функции, чтобы объект, выделенный в кучу, оставался в живых. Самый простой способ сделать это, чтобы переместить Box в вашу структуру:

struct Cont { 
    pub v: Box<i32> 
} 

impl Cont { 
    fn new(v: Box<i32>) -> Cont { 
     Cont { 
      v: v 
     } 
    } 
} 

fn f() -> Cont { 
    let v = Box::new(6); 
    Cont::new(v) 
} 

fn main() { 
    let c = f(); 

    println!("{}", c.v); 
} 

Если вы хотите структуру, которая способна хранить либо заимствованный указатель или владеющий Box (или другие виды смарта-указателей), мы может сделать его общим по признаку Borrow.

use std::borrow::Borrow; 

struct Cont<T> where T: Borrow<i32> { 
    pub v: T 
} 

impl<T> Cont<T> where T: Borrow<i32> { 
    fn new(v: T) -> Cont<T> { 
     Cont { 
      v: v 
     } 
    } 
} 

fn owned() -> Cont<Box<i32>> { 
    let v = Box::new(6); 
    Cont::new(v) 
} 

fn borrowed(v: &i32) -> Cont<&i32> { 
    Cont::new(v) 
} 

fn main() { 
    let c = owned(); 
    println!("{}", c.v); 

    let x = 123; 
    let c = borrowed(&x); 
    println!("{}", c.v); 
} 
+0

Что делать, если я хочу использовать ссылки в 'struct'? – dragostis

+0

Вы имеете в виду, что иногда вы хотите, чтобы структура просто заимствовала значение, а иногда и владела значением? –

+0

Я не хочу заимствовать. У меня может быть некоторое '& value', созданное в функции, и некоторые' Cont 'создаются и используются впоследствии, не возвращая ни одного из них или фактически передавая их дальше. Итак, '& value' будет иметь смысл, потому что я не хочу выделять это в куче. Есть ли способ использовать либо «Коробку», либо «Ref»? – dragostis

Смежные вопросы