首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >给(一个只接受引用的构造函数类型函数)一个值。

给(一个只接受引用的构造函数类型函数)一个值。
EN

Stack Overflow用户
提问于 2022-07-24 02:29:21
回答 1查看 34关注 0票数 1

假设有一个函数

代码语言:javascript
复制
fn basket_from_apple(apple: &'a mut Apple) -> Basket<'a>;

这就形成了一个篮子,里面的某个地方是苹果。我不能修改basket_from_apple的代码。在另一个包裹里。

我想给basket_from_apple苹果,所以我不需要坚持它,我希望篮子的下降,以破坏苹果连同篮子。

有办法生锈吗?例如,是否有某种类似盒子的对象,AppleBasket,我可以在某种程度上把苹果和篮子放进去?我想保持苹果的隐私,我想保持篮子的不可移动,但仍然可以通过不可更改的参考。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-24 04:51:02

您可以使用AppleBasket库定义您的ouroboros,该库允许创建包含从其他部分借用的部件的“自引用结构”。如下所示:

代码语言:javascript
复制
#[ouroboros::self_referencing]
struct AppleBasket {
    apple: Apple,
    #[borrows(mut apple)]
    #[covariant]
    basket: Basket<'this>,
}
impl AppleBasket {
    fn from_apple(a: Apple) -> AppleBasket {
        AppleBasket::new(a, |a: &mut Apple| basket_from_apple(a))
    }
}
// ...
fn some_func() {
    let a = Apple::new();
    let ab = AppleBasket::from_apple(a);
    // `ab` can be freely moved
    let b = ab.borrow_basket();
}

有时候,这是解决你所描述的问题的最好的方法,也是唯一的方法。然而,ouroboros有一些性能成本、不稳定的风险(如果有任何bug),以及一个一定会有些尴尬的API,因此您应该将它视为最后的手段;通常有一种方法可以避免借用,并以不同的方式将类型组合在一起。

  • 最基本的情况是,您可能实际上不需要保留Basket,但是可以编写一个函数,在需要时创建它。

有时候,

  • 库的设计很糟糕--作者并没有考虑支持一些有用的用例来保持Basket,但确实有,最好的解决方案是修改库(如果欢迎的话,还可以贡献改进)。(例如,Basket可以保存实现AsMut<Apple>的泛型类型的值,也可以保存自定义的Fruit特征)。

(但也可能有显而易见的或微妙的原因,为什么库的类型必须按照它们的方式工作。)。

  • --您可以将AppleBasket放在运行在线程或async任务上的循环中的局部变量中,后者接受指示它如何操作Basket的消息。消息通道(可能是合适的包装器类型)可以自由地传递。

  • 如果只有一个Apple (或一个有限的数字),那么您可以对它进行Box::leak()以获得一个&'static mut Apple,从而允许您创建一个Basket<'static>。这样做的缺点是不可能(安全地)恢复Apple所使用的内存,因此如果苹果定期被创建和销毁,就不应该这样做。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73095398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档