【问题标题】:Type annotation required when using `as_ref()` in `assert_eq!()`在 `assert_eq!()` 中使用 `as_ref()` 时需要类型注释
【发布时间】:2015-03-26 12:52:24
【问题描述】:

我在我的代码中使用了新的通用转换特征,并且体验到人体工程学的减少。如您在示例中所见,有问题的代码实现了AsRef<str> for [Ascii]

现在我想在assert_eq!() 中使用v.as_ref() 并期望v.as_ref() 使用提供的实现返回&str,因为assert_eq!() 的第二个参数是&str 类型。

没有AsRef<String> for [Ascii] 的实现,所以我认为只有PartialEq 的一种实现起作用:PartialEq<str> for &str

编译器没有遵循我的解释并抱怨所需的类型注释。如何避免显式注释以及为什么编译器无法找出AsRef<_> 的正确实现?

谢谢

#![feature(convert)]

struct Ascii { chr: u8 }

impl AsRef<str> for [Ascii] {
    fn as_ref(&self) -> &str {
        unsafe { ::std::mem::transmute(self) }
    }
}

fn main() {
    let v = [Ascii { chr: 65 }, Ascii { chr: 66 }];
    assert_eq!(v.as_ref(), "AB");
    // Workaround: explicit type annotation.
    //assert_eq!(AsRef::<str>::as_ref(&v[..]), "AB");
}

游戏围栏链接:http://is.gd/ZcdqXZ

<anon>:15:18: 15:26 error: type annotations required:
    cannot resolve `[Ascii] : core::convert::AsRef<_>` [E0283]
<anon>:15     assert_eq!(v.as_ref(), "AB");
                       ^~~~~~~~

【问题讨论】:

    标签: rust type-inference traits


    【解决方案1】:

    更详细地查看文档中的listed implementors of AsRef,您会发现那里还有另一个实现冲突:impl&lt;T&gt; AsRef&lt;[T]&gt; for [T]。所以它不能决定v.as_ref() 应该是&amp;str 还是&amp;[Ascii]

    【讨论】:

    • 为什么与已知的&amp;str 的比较不能帮助指导类型推断?使用具有多种目标类型的AsRef 的一些自定义实现,类型推断似乎理解“其他类型”并使用它来消除歧义。
    • @Shepmaster:assert_eq 做了一些稍微有点古怪的事情,这些事情有一点点干扰推理的历史,特别是过去几天的变化造成了一些麻烦。希望这种情况能在不久的将来得到解决,虽然我当然不能保证。
    • 但是it still fails with just a direct equality comparison,这让我觉得有第二个实现在某处更直接地发生冲突。但是,我也看到 order of items 有时会影响类型推断,这似乎是一个错误,所以我将其归档。
    猜你喜欢
    • 2018-09-07
    • 2017-12-15
    • 1970-01-01
    • 2021-07-26
    • 2019-12-12
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多