【问题标题】:How can I return boxed value?如何返回装箱值?
【发布时间】:2016-05-22 08:36:15
【问题描述】:

我基本上有一个函数可以创建一些需要在堆上分配的对象。我想要做的是从该函数返回一个包含对该堆分配值的引用的结构。

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

【问题讨论】:

    标签: rust heap-memory


    【解决方案1】:

    您不能返回仅包含指向对象的借用指针的结构,因为您的 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 trait 上通用。

    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);
    }
    

    【讨论】:

    • 如果我还想在struct 中使用引用怎么办?
    • 你的意思是有时你希望结构只是借一个值,有时是拥有这个值?
    • 我不想借。我可能在函数中创建了一些&amp;value,然后创建并使用了一些Conts,而没有返回它们中的任何一个,或者实际上将它们向下传递。那么&amp;value 会有意义,因为我不想在堆上分配它。有没有办法使用BoxRef
    • 例如:在一个函数中创建value,发送&amp;valueCont,有一些Cont方法返回一些i32,从这个函数返回i32
    • 我为我的答案添加了另一个解决方案。
    猜你喜欢
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多