如何抽象对值的引用或值本身? [英] How to abstract over a reference to a value or a value itself?

查看:32
本文介绍了如何抽象对值的引用或值本身?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特性,它为可以保存值的对象定义了一个接口.trait 有一种获取当前值的方法:

I have a trait that defines an interface for objects that can hold a value. The trait has a way of getting the current value:

pub trait HasValue<T> {
    fn get_current_value(&self) -> &T;
}

这很好,但我意识到根据实际的实现,如果 T 存储在一个字段中,有时返回引用很方便,有时返回 T 如果支持字段被跨线程共享(例如).我正在努力弄清楚如何在特征中表示这一点.我可以有这样的东西:

This is fine, but I realized that depending on the actual implementation, sometimes it's convenient to return a reference if T is stored in a field, and sometimes it's convenient to return a clone of T if the backing field was being shared across threads (for example). I'm struggling to figure out how to represent this in the trait. I could have something like this:

pub enum BorrowedOrOwned<'a, T: 'a> {
    Borrowed(&'a T),
    Owned(T)
}

impl<'a, T: 'a> Deref for BorrowedOrOwned<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        use self::BorrowedOrOwned::*;

        match self {
            &Borrowed(b) => b,
            &Owned(ref o) => o,
        }
    }
}

并更改 get_current_value() 以返回 BorrowedOrOwned 但我不确定这是惯用的.BorrowedOrOwned 有点让我想起 Cow 但因为 Cow 的重点是copy-on-write 并且我将丢弃任何在语义上似乎错误的写入.

And change get_current_value() to return a BorrowedOrOwned<T> but I'm not sure that this is idiomatic. BorrowedOrOwned<T> kind of reminds me of Cow<T> but since the point of Cow is to copy-on-write and I will be discarding any writes, that seems semantically wrong.

Cow 是抽象引用或拥有值的正确方法吗?有没有比 BorrowedOrOwned 更好的方法?

Is Cow<T> the correct way to abstract over a reference or an owned value? Is there a better way than BorrowedOrOwned<T>?

推荐答案

我建议你使用 Cow,因为你的 BorrowedOrOwnedCow<没有区别/code> 只是它的便利方法较少.任何持有 BorrowedOrOwned 对象的人都可以匹配它并获得拥有的值或对它的可变引用.如果您想避免因无法获取可变引用或对象本身而造成的混淆,以下解决方案也适用.

I suggest you use a Cow, since your BorrowedOrOwned has no difference to Cow except that it has fewer convenience methods. Anybody that gets a hold of a BorrowedOrOwned object could match on it and get the owned value or a mutable reference to it. If you want to prevent the confusion of being able to get a mutable reference or the object itself, the solution below applies, too.

对于您的用例,我只会使用 &T,因为没有理由让 API 变得更复杂.如果用户想要一个 usize,当 Tusize 时,他们可以简单地取消引用引用.

For your use case i'd simply stay with &T, since there's no reason to make the API more complex. If a user wants a usize, when T is usize, they can simply dereference the reference.

拥有的对象只有在您期望用户以拥有的方式实际处理它时才有意义.即便如此,Cow 旨在抽象您通过所有权传递的大/重对象,目的是不需要任何人克隆它.您的用例正好相反,您希望通过所有权传递小对象以防止用户需要复制小对象,而您正在复制它.

An owned object only makes sense, if you expect the user to actually process it in an owned fashion. And even then, Cow is meant to abstract over big/heavy objects that you pass by ownership for the purpose of not requiring anyone to clone it. Your use case is the opposite, you want to pass small objects by ownership to prevent users from needing to copy small objects, and instead you are copying it.

这篇关于如何抽象对值的引用或值本身?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆