用通用性状的多种实现方式将特定类型通知编译器的简洁方法是什么? [英] What is a concise way to inform the compiler of the specifc type with multiple implementations of a generic trait?

查看:76
本文介绍了用通用性状的多种实现方式将特定类型通知编译器的简洁方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个奇怪的类型推断问题,这使我有些挠头。

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

这篇关于用通用性状的多种实现方式将特定类型通知编译器的简洁方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆