问题描述
我遇到了一个奇怪的类型推断问题,这使我有些挠头。
I've come across an odd type inference problem that has me scratching my head a bit.
我正在为多种类型的结构实现泛型特征。我从& str
开始:
I'm implementing a generic trait on a struct for multiple types. I started with &str
:
struct Bar<'a> {
baz: &'a str,
}
trait Foo<T> {
fn foo(&self) -> T;
}
impl<'a> Foo<&'a str> for Bar<'a> {
fn foo(&self) -> &'a str {
self.baz
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_str_a() {
let bar = Bar { baz: "asd" };
assert_eq!("asd", bar.foo());
}
}
此方法有效-当我添加另一个实现时出现问题对于 u8
类型:
This works — the problem comes when I add another implementation for the u8
type:
struct Bar<'a> {
baz: &'a str,
}
trait Foo<T> {
fn foo(&self) -> T;
}
impl<'a> Foo<&'a str> for Bar<'a> {
fn foo(&self) -> &'a str {
self.baz
}
}
impl<'a> Foo<u8> for Bar<'a> {
fn foo(&self) -> u8 {
8
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_str_a() {
let bar = Bar { baz: "asd" };
assert_eq!("asd", bar.foo());
}
#[test]
fn test_u8() {
let bar = Bar { baz: "asd" };
assert_eq!(8 as u8, bar.foo());
}
}
在这种情况下,出现以下错误:
In this case, I get the following error:
error[E0283]: type annotations required: cannot resolve `Bar<'_>: Foo<_>`
--> src/main.rs:28:31
|
28 | assert_eq!("asd", bar.foo());
| ^^^
如果我将值存储在变量中,它将起作用:
If I store the value in a variable it works:
let foo: &str = bar.foo();
在我的生产代码中,我做了很多断言,这会使事情有些混乱。我也尝试过将 bar.foo()用作& str
,但这也失败了,因为编译器不知道 bar.foo()
的类型。我正在尝试为编译器找到一种简明的方式来知道类型。
In my production code, I do a lot of asserts and it would make things a bit messy. I've also tried bar.foo() as &str
but that also fails as the compiler doesn't know bar.foo()
's type either. I'm trying to find a concise way for the compiler to know the type.
推荐答案
使用以下方法将类型参数传递给特征一个 turbofish ( ::<>
):
Pass the type parameter to the trait using a turbofish (::<>
):
assert_eq!("asd", Foo::<&str>::foo(&bar));
您还可以使用以消除该方法属于哪个特征的歧义:
You could also use fully-qualified syntax to disambiguate which trait the method belongs to:
// This is "type-qualified" and equivalent to `Foo::<&str>::foo(&bar)`
assert_eq!("asd", <_ as Foo<&str>>::foo(&bar));
// This is "fully qualified"
assert_eq!("asd", <Bar as Foo<&str>>::foo(&bar));
这篇关于用通用性状的多种实现方式将特定类型通知编译器的简洁方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!