2017-02-05 3 views
4

サブタイプのある形質のためにRustにPartialEqを実装しようとしています。そのため、それらを箱のポインタとしてコンテナに追加して後で比較することができます。Rustの形質を持つAnyを使用する

use std::any::Any; 

trait Foo: Any {} 

struct Bar {} 

impl Foo for Bar {} 

struct Baz {} 

impl Foo for Baz {} 

impl PartialEq for Foo { 
    fn eq(&self, other: &Foo) -> bool { 
     let me = self as &Any; 
     let you = other as &Any; 
     if me.is::<Bar>() && you.is::<Bar>() { 
      true 
     } else if me.is::<Baz>() && you.is::<Baz>() { 
      true 
     } else { 
      false 
     } 
    } 
} 

fn main() { 
    let bar: Bar = Bar {}; 
    let baz: Baz = Baz {}; 
    let foo1: &Foo = &bar; 
    let foo2: &Foo = &baz; 
    println!("{:?}", foo1 == foo2); 
} 

Code example in Rust Playground

は、ここに私のスケールダウンの実装です。

私はこれをビルドすると、私が手:

rustc 1.17.0-nightly (0648517fa 2017-02-03) 
error: non-scalar cast: `&Foo + 'static` as `&std::any::Any + 'static` 
    --> <anon>:15:18 
    | 
15 |   let me = self as &Any; 
    |     ^^^^^^^^^^^^ 

error: non-scalar cast: `&Foo + 'static` as `&std::any::Any + 'static` 
    --> <anon>:16:19 
    | 
16 |   let you = other as &Any; 
    |     ^^^^^^^^^^^^^ 

error: aborting due to 2 previous errors 

混乱しています。私がここで間違っていることは何ですか?

編集:私がやろうとしていることはありませんアップキャスト、Anyを使用して意気消沈ですので、私は、これはWhy doesn't Rust support trait object upcasting?の複製であるとは考えていません。

さらに編集:はい、これは重複している - 申し訳ありませんが、私は私が(Anyにアップキャスト)ことをやったかというよりも、(BarBazタイプにダウンキャスト)やろうとしていたものを考えていました。しかし、それは言われている、私はまだ彼らがこれを行うAny example、なぜ理解していないと思います:let value_any = value as &Any;は、私のところでは動作しません。つまり、Joshua Entrekinはすばらしい答えを出しました。

最終編集私はタイプではなく特産品をアップキャストしているからです。Doh!。みんな、ありがとう!

+0

私はあなたのすべてのオプションを伝えるのにあまりにも新しい言語ですが、OOスタイルのサブタイトルを作成しようとしているようです。何らかの列挙型を使ってみましたか? –

+1

@JustinBlankそれを試しましたが、num AFAICTを配置する場所はありません。あなたは特性に列挙型を追加することはできません。グローバルな列挙型を作成すると、非常に複雑です。 Anyのためのドキュメントは、あなたのタイプがAnyなら、あなたが行っているキャストの種類を行うことができるはずです - したがって私の質問です。 –

+0

あなたの編集はわかりません。私は用語の違いがあると考えています。 '&Foo'を'&Any'に変換しようとしています。それは報奨です。どうしてあなたは降りようとしているのですか? [@JoshuaEntrekinも例を挙げています](https://play.rust-lang.org/?gist=3aae5b8349e3420497f3aa24f9e8ea7b&version=nightly&backtrace=0)これはうまくいくようです。 – Shepmaster

答えて

3

FooからAnyにアップキャストしようとしているため、これはWhy doesn't Rust support trait object upcasting?の複製です。あなたはFooas_anyメソッドを追加し、その上に実装する場合は、このコードは動作させることができます。

use std::any::Any; 

trait Foo: Any { 
    fn as_any(&self) -> &Any; 
} 

impl<T: Any> Foo for T { 
    fn as_any(&self) -> &Any { 
     self 
    } 
} 

struct Bar {} 

struct Baz {} 

impl PartialEq for Foo { 
    fn eq(&self, other: &Foo) -> bool { 
     let me = self.as_any(); 
     let you = other.as_any(); 
     if me.is::<Bar>() && you.is::<Bar>() { 
      true 
     } else if me.is::<Baz>() && you.is::<Baz>() { 
      true 
     } else { 
      false 
     } 
    } 
} 

fn main() { 
    let bar: Bar = Bar {}; 
    let baz: Baz = Baz {}; 
    let foo1: &Foo = &bar; 
    let foo2: &Foo = &baz; 
    println!("{:?}", foo1 == foo2); 
} 

私はここPlaygroundでそれを示しています。

+0

驚くばかり!ありがとう! –

+0

正しいことをして重複を指摘してくれてどうもありがとう。私はあなたが[tag:rust]の周りにぶら下がり、より多くの二重引用符を識別するのを助け、多分いくつかの重複しないものに答える機会を得ることを望む!^_ ^ – Shepmaster

関連する問題