#rust #traits #generic-programming #type-safety
#Ржавчина #Трейты #generic-программирование #безопасность типов
Вопрос:
Я пытаюсь разработать приложение для отслеживания дорог и разработал следующую структуру признаков (доступно на игровой площадке):
pub trait Source: Sized {
type Path: Path<Source = Self>;
}
pub trait Destination<S: Source>{ }
pub trait Path {
type Source: Source;
type Destination: Destination<Self::Source>;
}
Дело в том, что он не может скомпилироваться с ошибкой
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `<<Self as Source>::Path as Path>::Destination: Destination<Self>` is not satisfied
--> src/lib.rs:2:16
|
2 | type Path: Path<Source = Self>;
| ^^^^^^^^^^^^^^^^^^^ the trait `Destination<Self>` is not implemented for `<<Self as Source>::Path as Path>::Destination`
...
7 | pub trait Path {
| ---- required by a bound in this
8 | type Source: Source;
9 | type Destination: Destination<Self::Source>;
| ------------------------- required by this bound in `Path`
|
help: consider further restricting the associated type
|
1 | pub trait Source: Sized where <<Self as Source>::Path as Path>::Destination: Destination<Self> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
Это неясно. Я указал привязку связанного типа, type Path: Path<Source = Self>;
которая подразумевает привязку к связанному типу, указанному в сообщении об ошибке.
Но это должно запрещать реализацию с неправильными типами, а не объявлять ее такой, какая она есть. Есть ли способ это исправить?
Ответ №1:
Я нашел способ исправить это, указав еще один связанный тип, но причина исходной ошибки неясна. Вот рабочий пример:
pub trait Source: Sized {
type Path: Path<Source=Self, Destination=Self::Destination>;
type Destination: Destination<Self>; // Added associated type
}
pub trait Destination<S: Source>{ }
pub trait Path {
type Source: Source;
type Destination: Destination<Self::Source>;
}