为了账号安全,请及时绑定邮箱和手机立即绑定

派生特征会导致意外的编译器错误,但是手动实现有效

派生特征会导致意外的编译器错误,但是手动实现有效

神不在的星期二 2019-10-12 11:18:02
此代码(操场):#[derive(Clone)]struct Foo<'a, T: 'a> {    t: &'a T,}fn bar<'a, T>(foo: Foo<'a, T>) {    foo.clone();}...无法编译:error: no method named `clone` found for type `Foo<'a, T>` in the current scope  --> <anon>:7:9   |>16 |>     foo.clone();   |>         ^^^^^note: the method `clone` exists but the following trait bounds were not satisfied: `T : std::clone::Clone`help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `clone`, perhaps you need to implement it:help: candidate #1: `std::clone::Clone`添加use std::clone::Clone;并不会改变任何内容,因为它已经在序幕中了。当我删除#[derive(Clone)]并手动实现Clone时Foo,它会按预期编译!impl<'a, T> Clone for Foo<'a, T> {    fn clone(&self) -> Self {        Foo {            t: self.t,        }    }}这里发生了什么?#[derive()]-impls和手动的之间有区别吗?这是编译器错误吗?还有我没想到的东西?
查看完整描述

2 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

答案隐藏在错误消息中:


该方法clone存在,但不满足以下特征范围:T : std::clone::Clone


当您派生Clone(以及许多其他自动派生的类型)时,它会Clone在所有通用类型上添加一个界限。使用rustc -Z unstable-options --pretty=expanded,我们可以看到它变为:


impl <'a, T: ::std::clone::Clone + 'a> ::std::clone::Clone for Foo<'a, T> {

    #[inline]

    fn clone(&self) -> Foo<'a, T> {

        match *self {

            Foo { t: ref __self_0_0 } =>

            Foo{t: ::std::clone::Clone::clone(&(*__self_0_0)),},

        }

    }

}

在这种情况下,不需要绑定,因为泛型类型在引用后面。


现在,您将需要实现Clone自己。有一个Rust问题,但这是一种相对罕见的解决方法。


查看完整回答
反对 回复 2019-10-12
  • 2 回答
  • 0 关注
  • 526 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信