微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在枚举中使用 Copy 的 supertrait 时,Type 不会实现 Copy 错误

如何解决在枚举中使用 Copy 的 supertrait 时,Type 不会实现 Copy 错误

我是 Rust trait 的新手,所以这可能是由于对 supertrait、dyn 或其他任何东西的误解。我正在尝试在枚举中使用特征对象:

  • 在枚举的这个元素中可以使用的具体类型上设置一个特征
  • 确保枚举仍然可以派生 copy

最小的例子(在 Rust playground 上编译失败并出现相关错误)是:

#[derive(copy)]
enum Foo {
    A,B(dyn MyTraitWhichIscopy),}

trait MyTraitWhichIscopy: copy {}

错误是:

error[E0204]: the trait `copy` may not be implemented for this type
 --> src/lib.rs:1:10
  |
1 | #[derive(copy)]
  |          ^^^^
...
4 |     B(dyn MyTraitWhichIscopy),|       ---------------------- this field does not implement `copy`
  |
  = note: this error originates in a derive macro (in Nightly builds,run with -Z macro-backtrace for more info)

error: aborting due to prevIoUs error

For more information about this error,try `rustc --explain E0204`.

调用 rustc --explain E0204 后,我注意到以下情况,这可能是我遇到问题的地方:

The `copy` trait is implemented by default only on primitive types. If your
type only contains primitive types,you'll be able to implement `copy` on it.
Otherwise,it won't be possible.

有没有办法完成我想要做的事情?

解决方法

给定的代码有几个问题。

  1. 特征 Clone 不是对象安全的,因为方法 clone 指的是原始 self 类型,通过 dyn 抽象是未知的。您的特征具有超特征 Copy 并且 Copy 具有超特征 Clone,因此您的特征不是对象安全的,这意味着它不能用作特征对象,这也是称为“dyn特征”。

  2. Trait 对象是 ?Sized 这意味着它是一个动态大小的类型(DST,其大小在编译时未知)不能用作枚举字段,因为它也使枚举类型 {{ 1}}。在大多数情况下,DST 只能通过引用持有,实际上拥有时为 ?Sized,否则为 Box<dyn Trait>&dyn Trait

  3. &mut dyn Trait 需要超级特征 Copy,这意味着“任何实现 Clone 的类型都必须实现 Copy”。因此,当我们希望我们的自定义类型实现 Clone 时,我们应该先实现 Copy

结论:无法通过 trait 对象来约束一个类型来实现 CloneCopy,你必须使用一个 Clone 来保存你的 trait 对象,并手动使用一个定义克隆而不是标准的克隆特征并为装箱的特征对象实现克隆:

Box
,

您可以使用由您的特征绑定的泛型类型。另请注意,您还需要 Clone 才能拥有 Copy

#[derive(Clone,Copy)]
enum Foo<T: MyTraitWhichIsCopy> {
    A,B(T),}

trait MyTraitWhichIsCopy: Copy {}

Playground

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。