7

编者注:这个问题是在 Rust 1.0 之前和某些功能实现之前提出的。代码原样在今天有效。

我正在用 Rust 编写棋盘游戏 AI。游戏有多个规则集,我希望将规则逻辑与棋盘布局分开(它们目前是混合的)。在像 Ruby 这样的语言中,我会让单独的规则集实现相同的接口。在 Rust 中,我考虑过使用 trait 并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,现在允许结构上的特征边界。原来的答案也仍然有效。


您需要在 trait 实现中改进它,而不是在结构定义中。

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 回答