我有以下结构:
pub struct Foo<T> {
some_value: T,
}
impl<T> Foo<T> {
pub fn new(value: T) -> Self {
Self { some_value: value }
}
}
// Implement `Default()`, assuming that the underlying stored type
// `T` also implements `Default`.
impl<T> Default for Foo<T>
where
T: Default,
{
fn default() -> Self {
Self::new(T::default())
}
}
如果Foo::default()
实施T
,我希望Default
可用,但不可用。
是否可以在Rust中指定“条件实现”,当且仅当满足某些泛型类型特征约束时才实现特征?如果不满足约束,则不实现目标特征(在这种情况下为Default
)并且没有编译器错误。
换句话说,是否可以通过以下方式使用上面的通用结构?
fn main() {
// Okay, because `u32` implements `Default`.
let foo = Foo::<u32>::default();
// This should produce a compiler error, because `Result` does not implement
// the `Default` trait.
//let bar = Foo::<Result<String, String>>::default();
// This is okay. The `Foo<Result<...>>` specialisation does not implement
// `Default`, but we're not attempting to use that trait here.
let bar = Foo::<Result<u32, String>>::new(Ok(42));
}
答案 0 :(得分:3)
对于此特定情况,derive(Default)
提供的实施完全符合您的要求:
#[derive(Default)]
pub struct Foo<T> {
some_value: T,
}
另见:
答案 1 :(得分:2)
在修复次要语法问题之后,您的示例确实有效:
pub struct Foo<T> {
some_value: T,
}
impl<T> Foo<T> {
pub fn new(value: T) -> Self {
Self { some_value: value }
}
}
// Implement `Default()`, assuming that the underlying stored type
// `T` also implements `Default`.
impl<T> Default for Foo<T>
where
T: Default,
{
fn default() -> Self {
Self::new(T::default())
}
}
fn main() {}
答案 2 :(得分:0)
正如@Kornel的回答所指出的,结果是编译器已经有条件地实现了泛型结构的特征。
如果Default
满足在定义struct Foo<T>
的实现时指定的类型约束,则T
特征仅针对Default
实施。在这种情况下,约束被定义为where T: Default
。因此,如果Foo<T>
实施Default
,则T
仅实施Default
。
如上面的fn main()
示例所示,当Foo<T>
未实现Default
时,任何尝试使用T
的{{1}}实现都会产生编译器错误。