Я пришел из C ++, и у меня возникли проблемы с реализациями универсальных признаков.
Я пытаюсь создать библиотеку геометрии, которая выполняет некоторые операции как с полигонами, так и с открытыми путями, но ведет себя немного по-разному для каждого случая. В идеале мне нужна одна реализация геометрической операции в качестве метода, который может запрашивать у флага объект, над которым он работает,
Я также хочу, чтобы эта библиотека работала с любым объектом, который может выглядеть как многоугольник или открытый путь, а не только с моими типами данных, поэтому я хочу иметь признаки для PolygonLike
и OpenPathLike
, которые могут быть реализованы для любого типа. У меня есть код, который выглядит так:
trait Clipable {
fn closed() -> bool;
fn geom_func(&self) {
if Self::closed() {
println!("closed");
} else {
println!("open");
}
}
}
trait PolygonLike {}
trait OpenPathLike {}
struct Point(f64, f64);
type PointVec = Vec<Point>;
struct Poly(PointVec);
struct Path(PointVec);
impl PolygonLike for Poly {}
impl OpenPathLike for PointVec {}
impl<T> Clipable for T
where
T: PolygonLike,
{
fn closed() -> bool {
true
}
}
impl<T> Clipable for T
where
T: OpenPathLike,
{
fn closed() -> bool {
false
}
}
fn main() {
let pg = Poly(PointVec::new());
let op = Path(PointVec::new());
pg.geom_func();
op.geom_func();
}
Код не компилируется с:
error[E0119]: conflicting implementations of trait `Clipable`:
--> src/main.rs:28:1
|
24 | impl<T> Clipable for T where T: PolygonLike {
| ------------------------------------------- first implementation here
...
28 | impl<T> Clipable for T where T: OpenPathLike {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
В другом месте я читал, что выражение where
не используется средством проверки конфликтов, хотя ни один тип не реализует как PolygonLike
, так и OpenPathLike
.
Я понял, что это потому, что потребитель мог просто реализовать обе эти черты и сломать библиотеку. Чего я не понимаю, так это как обойти это.
Я видел другие посты, где люди использовали новые типы для ограничения общих реализаций, но я не могу понять, как заставить это работать для моего сценария.