2017-06-27 12 views
1

私はクラスにC++仮想関数のように動作しますラストで何かを実装しようとしているが、私はデータと基本構造体を持っているでしょうし、私は次の例のように、未定義の一部の機能を維持するだろう:C++の仮想関数に相当するRustとは何ですか?

class A { 
    int stuff; 
public: 
    virtual void foo(int a, int b) = 0; 
    void function_that_calls_foo() { /*...*/ foo(1, 2); /*...*/ } 
} 

class B: public A { void foo(int a, int b) { /* ... */ } } 

私は関数ポインタを使って実装しようとしていましたが、あまり成功しませんでした。私はAの関数で特性を使用し、他のクラスでAを実装することができますが、構造体のデータは失われます。 Rustでこのようなことを実行するには、最速の方法は何ですか?

struct A { 
    ... 
} 

impl A { 
    fn function_that_calls_foo(&self) { 
     ... 
     self.foo(a, b); 
     ... 
    } 
} 

struct B { 
    a: A; 
} 

impl B { 
    fn xxx(&self) { 
     a.function_that_calls_foo(1, 2); 
    } 

    fn foo(&self, a: i32, b: i32) {...} 
} 
+4

あなたは[形質オブジェクト](https://doc.rust-lang.org/book/second-edition/ch17-02-trait-objects.html)を探しています。 –

+3

だから、錆は非常に大事です。* Composition Over Inheritance *。 –

+5

これらの種類の質問は、 "私はどのようにクラスの継承を行うのですか?"あなたが解決しようとしている実際の問題(関数名の 'foo'と' xxx'での偽の問題ではなく)を解決し、あなたの新しいツールボックスを見て。クラス継承を直接Rustコードに変換しようとすると、それを動作させる方法がわかりますが、コードはもっと慣用的なRustコードと比べて非常に厄介かもしれません。 –

答えて

5

私は暗黙の追加「機能には、定義されることを呼び出すいくつかの機能を持っている」んだ

未定義の一部の機能を維持します。 E_net4 saysとして

traitを使用します。

trait Foo { 
    fn foo(&self, a: i32, b: i32) -> i32; 

    fn function_that_calls_foo(&self) { 
     println!("{}", self.foo(1, 2)); 
    } 
} 

あなたはその後、Baseのための形質を実装できます。

struct Base { 
    stuff: i32, 
} 

impl Foo for Base { 
    fn foo(&self, a: i32, b: i32) -> i32 { 
     self.stuff + a + b 
    } 
} 

そしてMatthieu M. saysとして、錆は、継承を持っているので、構図を使用していません。

struct Base { 
    stuff: i32, 
} 

impl Base { 
    fn reusable(&self) -> i32 { 
     self.stuff + 1 
    } 
} 

struct Alpha { 
    base: Base, 
    modifier: i32, 
} 

impl Foo for Alpha { 
    fn foo(&self, a: i32, b: i32) -> i32 { 
     (self.base.reusable() + a + b) * self.modifier 
    } 
} 

型パラメータによって制約されるgenericを取ることによって、2つの概念も同様に実現します。


私は強く2番目ですDietrich Epp's point。新しい言語を使用するには、新しいパラダイムをチェックする必要があります。コードを再利用するための継承は、それをサポートする言語であっても、通常は素晴らしいアイデアではありません。代わりに、小さなビルディングブロックを作成し、それらを組み合わせてください。

+1

答えの中で最も重要な部分は、「新しい言語を使用するには、新しいパラダイムをチェックする必要があります」と私の意見で言います。あまりにもしばしば忘れられた。 – Boiethios

関連する問題