У меня есть черта со связанным типом:
pub trait Speak {
type Error;
fn speak(&self) -> Result<String, Self::Error>;
}
Реализация этой черты:
#[derive(Default)]
pub struct Dog;
impl Speak for Dog {
type Error = ();
fn speak(&self) -> Result<String, Self::Error> {
Ok("woof".to_string())
}
}
И функция, возвращающая экземпляр этой реализации:
pub fn speaker() -> impl Speak {
Dog::default()
}
Я знаю, что в этом примере я мог бы просто использовать Dog
в качестве возвращаемого типа, но в моем реальном коде я должен использовать impl Speak
вместо этого (вышеупомянутая функция фактически генерируется макросом).
Насколько я понимаю, нотация impl Trait
позволяет компилятору выяснить, какой конкретный тип действительно возвращен, поэтому я ожидаю, что следующая функция будет компилироваться правильно, потому что speaker()
возвращает Dog
и что Dog::Error
это тип ()
:
fn test() -> Result<String, ()> {
speaker().speak()
}
детская площадка
Вместо этого я получаю следующую ошибку:
error[E0308]: mismatched types
--> src/lib.rs:21:5
|
20 | fn test() -> Result<String, ()> {
| ------------------ expected `std::result::Result<std::string::String, ()>` because of return type
21 | speaker().speak()
| ^^^^^^^^^^^^^^^^^ expected (), found associated type
|
= note: expected type `std::result::Result<_, ()>`
found type `std::result::Result<_, <impl Speak as Speak>::Error>`
Это какесли компилятор не может (на данный момент) определить тип возврата функции speaker
.
Кто-то что-то упустил, компилятор или я?