"ошибка: границы признаков недопустимы в определениях структуры" при попытке использовать полиморфизм
Примечание редактора: этот вопрос был задан до 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());
}