问题描述
此代码():
#[derive(Clone)]
struct Foo<'a, T: 'a> {
t: &'a T,
}
fn bar<'a, T>(foo: Foo<'a, T>) {
foo.clone();
}
...无法编译:
error[E0599]: no method named `clone` found for struct `Foo<'a, T>` in the current scope
--> src/main.rs:16:9
|
3 | struct Foo<'a, T: 'a> {
| ---------------------
| |
| method `clone` not found for this
| doesn't satisfy `Foo<'_, T>: std::clone::Clone`
...
16 | foo.clone();
| ^^^^^ method not found in `Foo<'a, T>`
|
= note: the method `clone` exists but the following trait bounds were not satisfied:
`T: std::clone::Clone`
which is required by `Foo<'_, T>: std::clone::Clone`
help: consider restricting the type parameter to satisfy the trait bound
|
3 | struct Foo<'a, T: 'a> where T: std::clone::Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
使用添加使用std :: clone :: Clone;
不会更改任何内容,因为它已经处于序幕中。
Adding use std::clone::Clone;
doesn't change anything, as it's already in the prelude anyway.
何时我删除了#[derive(Clone)]
,并为 Foo手动实现了
,它会按预期编译! Clone
。
When I remove the #[derive(Clone)]
and manually implement Clone
for Foo
, it compiles as expected!
impl<'a, T> Clone for Foo<'a, T> {
fn clone(&self) -> Self {
Foo {
t: self.t,
}
}
}
这是怎么回事?
-
#[derive()]之间是否有区别?
-impls和手动工具? - 这是编译器错误吗?
- 还有我没想到的东西吗?
- Is there a difference between
#[derive()]
-impls and manual ones? - Is this a compiler bug?
- Something else I didn't think of?
推荐答案
答案被隐藏在错误消息中:
The answer is buried in the error message:
= note: the method `clone` exists but the following trait bounds were not satisfied:
`T: std::clone::Clone`
which is required by `Foo<'_, T>: std::clone::Clone`
派生 Clone
(以及许多其他自动派生的类型)时,它会添加克隆
绑定到所有通用类型上。使用 rustc -Z不稳定选项--pretty = expanded
,我们可以看到它变成了:
When you derive Clone
(and many other automatically-derived types), it adds a Clone
bound on all generic types. Using rustc -Z unstable-options --pretty=expanded
, we can see what it becomes:
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)),},
}
}
}
在这种情况下,不需要绑定,因为通用类型在引用后面。
In this case, the bound is not needed because the generic type is behind a reference.
现在,您将需要自己实现 Clone
。 ,但这是一种相对罕见的解决方法
For now, you will need to implement Clone
yourself. There's a Rust issue for this, but it's a comparatively rare case with a workaround.
这篇关于派生特征会导致意外的编译器错误,但是手动实现有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!