【问题标题】:Get Box Pointer from reference in rust从 rust 中的引用中获取 Box Pointer
【发布时间】:2021-04-24 07:43:27
【问题描述】:

假设我有这样的功能:

fn foo(item: &FooType) -> Box<FooType>{
    Box::new(item)
}

我收到以下错误:

类型不匹配:预期枚举 FooType,发现 &amp;FooType

我假设我需要做一些参考/拳击和终身魔术,但作为一个 rust 初学者,我不能 100% 确定如何让它工作。

【问题讨论】:

  • 这通常是不可能的,除非FooType 是可克隆的。原因很简单:Box&lt;FooType&gt; 拥有 FooType,但 &amp;FooType 不拥有。

标签: pointers rust reference smart-pointers lifetime


【解决方案1】:

我认为没有明确的答案,因为这取决于您的期望。

如果你想获得一个堆分配的克隆你想保持可用的东西,那么在foo1() 中克隆会有所帮助。

更好的解决方案可能是传递 而不是引用,如 foo2(),因为这样调用站点可以决定是否需要克隆,或者是否将原始值移动到盒子就够了。

您可能还希望该框保存引​​用而不是值,如 foo3() 中那样,但这对我来说就像是代码味道(许多间接导致生命周期的推理非常复杂)。

#[derive(Debug, Clone)]
struct FooType {
    value: usize,
}

fn foo1(item: &FooType) -> Box<FooType> {
    Box::new(item.clone())
}

fn foo2(item: FooType) -> Box<FooType> {
    Box::new(item)
}

fn foo3(item: &FooType) -> Box<&FooType> {
    Box::new(item)
}

fn main() {
    let ft_a = FooType { value: 12 };
    let bft_a = foo1(&ft_a);
    println!("bft_a: {:?}", bft_a);
    println!("ft_a: {:?}", ft_a);
    println!("~~~~~~~~~~~~~~~~~~");
    let ft_b = FooType { value: 34 };
    let bft_b = foo2(ft_b);
    println!("bft_b: {:?}", bft_b);
    //  println!("ft_b: {:?}", ft_b); // borrow of moved value: `ft_b`
    println!("ft_b is consumed");
    println!("~~~~~~~~~~~~~~~~~~");
    let ft_c = FooType { value: 56 };
    let bft_c = foo2(ft_c.clone());
    println!("bft_c: {:?}", bft_c);
    println!("ft_c: {:?}", ft_c);
    println!("~~~~~~~~~~~~~~~~~~");
    let ft_d = FooType { value: 78 };
    let bft_d = foo3(&ft_d);
    println!("bft_d: {:?}", bft_d);
    println!("ft_d: {:?}", ft_d);
}
/*
bft_a: FooType { value: 12 }
ft_a: FooType { value: 12 }
~~~~~~~~~~~~~~~~~~
bft_b: FooType { value: 34 }
ft_b is consumed
~~~~~~~~~~~~~~~~~~
bft_c: FooType { value: 56 }
ft_c: FooType { value: 56 }
~~~~~~~~~~~~~~~~~~
bft_d: FooType { value: 78 }
ft_d: FooType { value: 78 }
*/

【讨论】:

    【解决方案2】:

    编译器抱怨是因为在函数的签名中您将Box&lt;FooType&gt; 指定为返回类型,并且当您将ìtem 包装在Box 中时,您给它一个Box&lt;&amp;FooType&gt;

    更改函数的签名,使其接收FooType,而不是像这样对它的引用:

    fn foo(item: FooType) -> Box<FooType>{
        Box::new(item)
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 2021-01-31
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      相关资源
      最近更新 更多