2016-12-14 10 views
2

私は、値を保持できるオブジェクトのインタフェースを定義する特性を持っています。特色は、現在の値を取得する方法があります。値または値自体への参照を抽象化する方法はありますか?

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

これは結構ですが、私はTがフィールドに格納され、時にはそれはですされている場合、実際の実装に依存し、時にはそれが参照を返すために便利だということを実現しましたバッキングフィールドがスレッド間で共有されている場合(たとえば)、Tのクローンを返すのが便利です。私はこの特性をどのように表現するかを考え出すのに苦労しています。私はこのようなものかもしれない:

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, 
     } 
    } 
} 

をそしてBorrowedOrOwned<T>を返すようにget_current_value()を変更するが、私は、これは慣用的であることはよく分かりません。 BorrowedOrOwned<T>の種類は私にCow<T>を覚えていますが、Cowの点はになりますので、コピー時にはにコピーされ、意味的には間違っていると思います。

Cow<T>は、参照または所有された値を抽象する正しい方法ですか? BorrowedOrOwned<T>よりも良い方法はありますか?

+0

関連するタイプ「B:Borrow 」が返されますか? –

+0

@ChrisEmerson私はそれを行うことのトレードオフがどういうわけか分かりませんので、私は確信していません。少し拡大していただけますか?これは一般的に有用な質問のように思えるので、私の特定の状況に対処しなくてもすべての回答に興味があります。 –

+0

私は実際に直接役立たないと思う。あなたはまだ「牛」のようなものが必要になります。 –

答えて

7

BorrowedOrOwnedにはCowとの違いがないので、便利な方法が少ないことを除いて、Cowを使用することをおすすめします。 BorrowedOrOwnedオブジェクトを保持する人は誰でもそれにマッチして、所有されている値またはそれに対する変更可能な参照を取得できます。変更可能な参照またはオブジェクト自体を取得できるという混乱を避けたい場合は、以下の解決策も適用されます。

APIをより複雑にする理由がないので、私は&Tのままにしておきます。ユーザがusizeを望む場合、Tusizeの場合、参照を単純に逆参照できます。

所有しているオブジェクトは、ユーザーが所有している方法で実際に処理することを期待する場合にのみ意味があります。それでも、Cowは、誰も要求しないためにオーナーシップで渡した大きい/重いオブジェクトを抽象化することを意味します。cloneあなたのユースケースは逆です。小さいオブジェクトを所有権で渡して、小さなオブジェクトをコピーする必要がなくなり、代わりにコピーしたいとします。

+0

アドバイスをいただきありがとうございます。問題を簡略化するために、私は時には '&T'と' T 'を返す必要のある時を返そうとする理由を誤っていました。実装が 'Arc >'の中に 'T'を格納している場合、単に'&T'を返すことはできません。 'T'はクローン化されなければならず、クローンは関数のスタック上に存在するので、そのクローンへの参照を返すことはできません。それが参考になることを願っています。 PS。 RBRであなたと話すのはすばらしかった:) –

+1

ああ!それは理にかなっています。さて、あなたの 'BorrowedOrOwned'は' enum Borrow <'a, T> {Ref(& 'a T)、Arc(Arc >)、Rc(Rc >)} 'のようなものでなければなりません。多くのユースケースでは 'RefCell'が必要ではないかもしれませんが、ユースケースについてもっと知らなくても解決できると思いますので、' RefCell'によって複雑になります。 –

+0

非常に真実。私はそれをちょっと試してみる必要がありますが、私はあなたが私の質問に「牛」について答えてくれたので、これを答えにするつもりです。これは間違いなく正しい方向に私を指摘しています。ありがとう –

関連する問題