Обратите внимание, что указание направления в общем параметре c, как в конечном коде, означает, что направление статически определяется для каждого экземпляра Reader
и не может быть изменено. Если это то, что вы хотите, вы можете сделать это, имея Direction
быть признаком и Forward
и Backward
быть типами, которые реализуют эту черту:
trait Direction{}
struct Forward{}
impl Direction for Forward {}
struct Backward{}
impl Direction for Backward {}
struct Reader<D: Direction> {
data: Vec<usize>,
data_it: Box<dyn Iterator<Item = usize>>,
direction: D,
}
impl Reader<Forward> {
fn read (&mut self) { unimplemented!(); }
}
impl Reader<Backward> {
fn read (&mut self) { unimplemented!(); }
}
Если ваша структура Reader
должна также включают некоторые общие функции, которые не зависят от направления, вы можете добавить эти функции в дополнительный общий блок c impl
:
impl<T: Direction> Reader<T> {
fn common_function (&self) { unimplemented!(); }
}
Поскольку вы хотите иметь возможность иметь экземпляры каждого и переключения между ними во время выполнения, вам нужно будет определить интерфейс в признаке, а затем использовать ссылки на этот признак. Кроме того, чтобы иметь возможность доступа к общим функциям из реализации черты, они также должны быть определены в супертрассе:
pub trait Direction{}
pub struct Forward{}
impl Direction for Forward {}
pub struct Backward{}
impl Direction for Backward {}
pub trait CommonReader {
fn common_function (&self);
}
pub trait ReaderItf: CommonReader {
fn read (&mut self);
}
pub struct Reader<D: Direction> {
pub data: Vec<usize>,
pub data_it: Box<dyn Iterator<Item = usize>>,
pub direction: D,
}
impl ReaderItf for Reader<Forward> {
fn read (&mut self) { self.common_function(); }
}
impl ReaderItf for Reader<Backward> {
fn read (&mut self) { unimplemented!(); }
}
impl<T: Direction> CommonReader for Reader<T> {
fn common_function (&self) { unimplemented!(); }
}
// And you use it like this wherever you want to switch at runtime:
pub fn use_reader (r: &mut dyn ReaderItf) {
r.read();
}
Playground