What is a concise way to inform the compiler of the specifc type with multiple implementations of a generic trait?

☆樱花仙子☆ 提交于 2019-11-28 11:08:05

问题


I've come across an odd type inference problem that has me scratching my head a bit.

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());
    }
}

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();

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.


回答1:


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));


来源:https://stackoverflow.com/questions/48263001/what-is-a-concise-way-to-inform-the-compiler-of-the-specifc-type-with-multiple-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!