Используйте черту для поведения, которое имеет несколько реализаций. Существует множество комбинаций способов их использования, вот один из них:
use std::marker::PhantomData;
trait Core {
fn print();
}
#[derive(Debug, Default)]
struct PrintA;
impl Core for PrintA {
fn print() {
print!("a")
}
}
#[derive(Debug, Default)]
struct PrintB;
impl Core for PrintB {
fn print() {
print!("b")
}
}
#[derive(Debug, Default)]
struct Thing<C>(PhantomData<C>);
impl<C: Core> Thing<C> {
fn common() {
print!(">");
C::print();
println!("<")
}
}
fn main() {
Thing::<PrintA>::common();
Thing::<PrintB>::common();
}
Или другое:
trait Core {
fn select<'a>(left: &'a i32, right: &'a i32) -> &'a i32;
}
#[derive(Debug, Default)]
struct Left;
impl Core for Left {
fn select<'a>(left: &'a i32, _right: &'a i32) -> &'a i32 {
left
}
}
#[derive(Debug, Default)]
struct Right;
impl Core for Right {
fn select<'a>(_left: &'a i32, right: &'a i32) -> &'a i32 {
right
}
}
#[derive(Debug, Default)]
struct Thing<C> {
kind: C,
left: i32,
right: i32,
}
impl Thing<Left> {
fn new_left(left: i32, right: i32) -> Self {
Self {
left,
right,
kind: Left,
}
}
}
impl Thing<Right> {
fn new_right(left: i32, right: i32) -> Self {
Self {
left,
right,
kind: Right,
}
}
}
impl<C: Core> Thing<C> {
fn add_one(&self) -> i32 {
self.select() + 1
}
fn select(&self) -> &i32 {
C::select(&self.left, &self.right)
}
}
pub fn l() -> i32 {
let l = Thing::new_left(100, 200);
l.add_one()
}
pub fn r() -> i32 {
let r = Thing::new_right(100, 200);
r.add_one()
}
Следует отметить, что последний пример компилируется в следующий код LLVM IR:
define i32 @_playground_l() {
start:
ret i32 101
}
define i32 @_playground_r() {
start:
ret i32 201
}
Я рассмотрел вопрос о переносе всего кода в черту, но это не показалось уместным: динамическая диспетчеризация не нужна, почти все методы не будут иметь параметр self
- черты не подразумевают динамическую отправку. См Мономорфизация .
- методы черт не требуют
self
Если бы не ремонтопригодность, я просто скопировал бы весь код
Похоже на то, что макросы могут подойти, если вы не можете обрабатывать черты.