У меня есть две черты:
trait Foo {}
trait Bar {}
struct FooImpl;
impl Foo for FooImpl {}
struct BarImpl;
impl Bar for BarImpl {}
И третий тип, в который я хочу преобразовать:
struct Baz;
trait IntoBaz {
fn into(self) -> Baz;
}
Я не могу определить две impl
с IntoBaz
по двум признакам из-за слаженности, поэтому вместо этого я обертываю одну:
struct FooWrapper<F>(F)
where
F: Sized;
impl<F: Foo + Sized> From<F> for FooWrapper<F> {
fn from(f: F) -> FooWrapper<F> {
FooWrapper(f)
}
}
impl<F: Foo + Sized> IntoBaz for FooWrapper<F> {
fn into(self) -> Baz {
Baz
}
}
И другую не оборачиваю:
impl<B: Bar> IntoBaz for B {
fn into(self) -> Baz {
Baz
}
}
fn do_thing<B: IntoBaz>(b: &B) {}
fn main() {
do_thing(&BarImpl);
}
Пока все хорошо, но почему нет?Эта линия работает?
fn main() {
do_thing(&FooImpl);
}
Мотивация
Я пытаюсь добавить поддержку io::Write
в библиотеку с поддержкой fmt::Write
без внесения критических изменений.
Самым простым способом было бы определить некоторую внутреннюю черту Write
, которая покрывает общее поведение, но проблема согласованности означает, что я не могу просто записать From<io::Write>
экземпляров во внутреннюю черту.
Я пытался обернуть io::Write
экземпляры, чтобы сделать явное приведение, чтобы компилятор расставил приоритеты для более короткого пути и избежал несогласованности, но он не будет автоматически приводиться с использованием экземпляра From
.