[英]Can't implement a trait I don't own for all types that implement a trait I do own
pub trait AllValues {
fn all_values() -> Vec<Self> where Self: std::marker::Sized;
}
use rand::Rand;
use rand::Rng;
impl<T: AllValues + Sized> Rand for T {
fn rand<R: Rng, T>(rng: &mut R) -> T {
let values = T::all_values();
let len = values.len();
if len == 0 {
panic!("Cannot pick a random value because T::all_values() returned an empty vector!")
} else {
let i = rng.gen_range(0, len);
values[i]
}
}
}
前面的代码产生以下编译时错误:
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
--> src/lib.rs:137:1
|
137 | impl<T: AllValues + Sized> Rand for T {
| ^
根据这里提到的实现特性的限制,我应该能够为AllValues
实现Rand
,因为AllValues
是在我的箱子中定义的。 一致性/孤儿impl
规则实际上允许这样做吗? 如果是这样,为实现AllValues
事物实现Rand
的正确方法是什么?
我应该能够为
AllValues
实现Rand
,因为AllValues
是在我的箱子中定义的。
不,您只能为未定义的类型实现自己的特征AllValues
。 你不能从逻辑上跳到实现一个你也没有定义的无关特征。
有两个注意事项需要记住:
Rand
!T
实现Rand
。为实现
AllValues
事物实现Rand
的正确方法是什么?
我不相信有一个。 我只是介绍一个包装器类型,它保存一个值或一个值的引用,该值实现了您的特征并为此实现了Rand
。
也可以看看:
我现在明白我的解释错误在哪里。 引用本书的特征部分:
实现 trait 还有一个限制:要么是 trait 要么是你要实现它的类型必须由你定义。 或者更准确地说,其中之一必须与您正在编写的 impl 定义在同一个 crate 中。
(加了重点。)
由于我试图实现一个特征,我必须将其理解为“特征或您正在为其实现的特征”。 这个关于最终实现的 rfc 的讨论特别提到了一个与我提出的类似的案例: impl<T: Copy> Clone for T
是不允许的。
按照其他地方的建议创建包装器类型是解决此问题的一种方法。 假设类型实现的所有权允许它,为每个具体实例显式实现特征,(可选地用宏压缩代码),正如这里建议的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.