[英]Implementing a foreign trait for any type implementing your trait
I want to provide default values for structs to be used only within tests (and not accidentally in production).我想为仅在测试中使用的结构提供默认值(而不是在生产中意外使用)。 I thought that I could make the defaults opt-in by defining my own trait TestDefault
and implement Default
for any type that implements it.我认为我可以通过定义我自己的特征TestDefault
并为实现它的任何类型实现Default
来选择默认值。 Then, one could access all the features of the standard Default
trait using something like this然后,可以使用类似这样的方式访问标准Default
特征的所有功能
use TestDefault; // TestStruct (defined in my crate) implements TestDefault, thus also Default
let test_struct = TestStruct::default();
To clarify, I want to implement a foreign trait on local type, which should be allowed, but with an artificial layer of indirection to make it opt-in.澄清一下,我想在本地类型上实现一个外部特征,这应该是允许的,但是有一个人为的间接层来让它选择加入。
I've tried我试过了
pub trait TestDefault {
fn test_default() -> Self;
}
impl Default for TestDefault {
fn default() -> Self {
Self::test_default()
}
}
where the compiler complains that error[E0782]: trait objects must include the 'dyn' keyword
, inserting it instead causes it to fail because error[E0038]: the trait 'TestDefault' cannot be made into an object
.编译器抱怨error[E0782]: trait objects must include the 'dyn' keyword
,插入它反而会导致它失败,因为error[E0038]: the trait 'TestDefault' cannot be made into an object
。
Then I tried然后我尝试了
impl<T> Default for T
where
T: TestDefault,
{
fn default() -> T {
T::test_default()
}
}
and got并得到
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
which probably hints at the actual error, but I don't entirely understand it.这可能暗示了实际的错误,但我并不完全理解。 Is there any way to do this?有没有办法做到这一点? Or get opt-in default some other way?或者以其他方式获得选择加入默认值?
Not a direct answer to your question, but why don't you use the #[cfg(test)]
annotation to only enable the Default
implementation when testing?不是对您的问题的直接回答,但您为什么不使用#[cfg(test)]
注释仅在测试时启用Default
实现?
struct MyStruct {
data: u32,
}
#[cfg(test)]
impl Default for MyStruct {
fn default() -> Self {
Self { data: 42 }
}
}
fn main() {
let s = MyStruct::default(); // FAILS
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let s = MyStruct::default(); // WORKS
assert_eq!(s.data, 42);
}
}
> cargo test
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
> cargo run
error[E0599]: no function or associated item named `default` found for struct `MyStruct` in the current scope
--> src/main.rs:13:23
|
1 | struct MyStruct {
| --------------- function or associated item `default` not found for this
...
13 | let s = MyStruct::default(); // FAILS
| ^^^^^^^ function or associated item not found in `MyStruct`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `default`, perhaps you need to implement it:
candidate #1: `Default`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.