![](/img/trans.png)
[英]Why does the rust compiler require a type annotation for Option<&impl Trait>?
[英]Why does the compiler not infer the concrete type of an associated type of an impl trait return value?
我有一个关联类型的特征:
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
是type ()
:
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
函数的返回类型。
谁缺少某些东西,编译器还是我自己?
使用-> impl Speak<Error = ()>
作为返回类型speaker()
问题在于,编译器仅从签名就需要调用者可以实际使用该函数的足够信息。 如果仅返回impl Speak
,则编译器知道speak()
返回Result<String, ???>
-错误类型未知,因此编译器会发出错误。
编译器无法在此处推断任何内容。 它不能从呼叫站点推断错误类型,因为在返回位置的impl Trait
不允许从呼叫站点推断错误。 它不能从实现中推断出错误类型,因为这将意味着调用者的类型检查是否取决于实现,而这不是impl Trait
工作方式。 调用者必须始终仅在签名信息存在的情况下进行类型检查; 此后才插入具体类型。
你是。
您从未指定关联的Error
类型,因此您不能承担任何责任。 即使确实是()
,编译器也不允许您使用该知识。 要解决此问题,只需指定Error
是什么:
pub fn speaker() -> impl Speak<Error = ()> {
Dog::default()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.