尝试使用多态时,“错误:结构定义中不允许使用特征边界”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试使用多态时,“错误:结构定义中不允许使用特征边界”相关的知识,希望对你有一定的参考价值。

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

我在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
答案

问题中提供的代码适用于所有最新版本的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());
}

以上是关于尝试使用多态时,“错误:结构定义中不允许使用特征边界”的主要内容,如果未能解决你的问题,请参考以下文章

Jakson 多态枚举案例

在Java中使用多态时,是否存在对象的隐式转换?

动态方法分派和运行时多态性错误

MySQL 上的 @GeneratedValue 多态抽象超类

使用 QueryDsl 的多态 where 子句

将多态案例类转换为 json 并返回