【发布时间】:2022-09-26 11:01:30
【问题描述】:
我想为仅在测试中使用的结构提供默认值(而不是在生产中意外使用)。我认为我可以通过定义我自己的特征 TestDefault 并为实现它的任何类型实现 Default 来选择默认值。然后,可以使用类似这样的东西访问标准Default trait 的所有功能
use TestDefault; // TestStruct (defined in my crate) implements TestDefault, thus also Default
let test_struct = TestStruct::default();
澄清一下,我想在本地类型上实现一个外部特征,这应该是允许的,但是有一个人为的间接层来让它选择加入。
我试过了
pub trait TestDefault {
fn test_default() -> Self;
}
impl Default for TestDefault {
fn default() -> Self {
Self::test_default()
}
}
编译器抱怨error[E0782]: trait objects must include the \'dyn\' keyword,插入它反而会导致它失败,因为error[E0038]: the trait \'TestDefault\' cannot be made into an object。
然后我尝试了
impl<T> Default for T
where
T: TestDefault,
{
fn default() -> T {
T::test_default()
}
}
并得到
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src/lib.rs:158:14
|
158 | impl<T> Default for T
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
这可能暗示了实际的错误,但我并不完全理解。有没有办法做到这一点?或者以其他方式获得选择加入默认值?
-
@ChayimFriedman 谢谢,但我不这么认为。
TestStruct将在我的 crate 中定义。所以我仍然会在应该允许的本地类型上实现一个外部特征,但是有一个人为的间接层。 -
那为什么不直接实现
Default呢?无论如何,如果你使用泛型,你就可以为任何类型实现它,而不仅仅是那些在你的 crate 中定义的类型。 -
要点是您只能在手动编写
use TestDefault时访问默认实现,因为它只是测试的便利功能,而不是实际的默认设置。我从extension traits 的工作方式中获得灵感,您必须通过use他们才能访问相关的方法。但它不会是通用的,因为我必须为我的每个结构手动实现TestDefault。 -
即使您想要的东西被允许,情况也不会如此 - 只要
Default本身存在,Default实现将始终可用。