7

編集者注: この質問は、Rust 1.0 および特定の機能が実装される前に行われました。コードは現状のままで動作します。

RustでボードゲームのAIを書いています。ゲームには複数のルールセットがあり、ルール ロジックをボード レイアウトから分離したいと考えています (現在は混在しています)。Ruby のような言語では、別々のルール セットに同じインターフェイスを実装させます。Rustでは、トレイトを使用し、Board使用したいルールセットでパラメーター化することを考えました(例:Board<Rules1>::new())。

この特性を実装するオブジェクトを構造体 ( などBoard) に保存することはできません。Rulesをに変えることはできenumますが、列挙型のメンバーに対して個別の実装を定義できないため、少し面倒に見えます。パターン マッチングを使用するとうまくいきますが、構造体軸ではなく関数軸に沿って機能が分割されます。これは私が一緒に暮らさなければならないものですか、それとも何らかの方法がありますか?

次のコードは、私が使用したいものです。

pub struct Rules1;
pub struct Rules2;

trait Rules {
    fn move_allowed() -> bool;
}

impl Rules for Rules1 {
    fn move_allowed() -> bool {
        true
    }
}

impl Rules for Rules2 {
    fn move_allowed() -> bool {
        false
    }
}

struct Board<R: Rules> {
    rules: R
}

fn main() {}

次のエラーが発生します。

test.rs:20:1: 22:2 error: trait bounds are not allowed in structure definitions
test.rs:20 struct Board<R: Rules> {
test.rs:21     rules: R
test.rs:22 }
error: aborting due to previous error
4

1 に答える 1

11

質問に示されているコードは、Rust の最近のすべてのバージョンで機能し、構造体の特性境界が許可されるようになりました。元の答えもまだ有効です。


構造体の定義ではなく、特性の実装でそれを改良する必要があります。

pub struct Rules1;
pub struct Rules2;

trait Rules {
    fn move_allowed(&self) -> bool;
}

impl Rules for Rules1 {
    fn move_allowed(&self) -> bool {
        true
    }
}

impl Rules for Rules2 {
    fn move_allowed(&self) -> bool {
        false
    }
}

struct Board<R> {
    rules: R,
}

impl<R: Rules> Board<R> {
    fn move_allowed(&self) -> bool {
        self.rules.move_allowed()
    }
}

fn main() {
    let board = Board { rules: Rules2 };
    assert!(!board.move_allowed());
}
于 2014-06-23T10:21:22.173 に答える