"ошибка: границы признаков недопустимы в определениях структуры" при попытке использовать полиморфизм

Примечание редактора: этот вопрос был задан до Rust 1.0 и до реализации определенных функций. Код как есть работает сегодня.

Я пишу настольную игру AI в Rust. Есть несколько наборов правил для игры, и я хотел бы отделить логику правил от макета доски (в настоящее время они смешаны). В таком языке, как 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

1 ответ

Решение

Код, представленный в этом вопросе, работает на всех последних версиях 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());
}
Другие вопросы по тегам