铁锈-性状受特征限制吗?

时间:2020-04-23 16:44:42

标签: rust traits

我最近开始使用rust,正在图书馆中工作。 以下工作正常,但看起来像代码重复

#[cfg(feature = "serde_support")]
use serde::Serialize;

#[cfg(not(feature = "serde_support"))]
pub struct Teststruct<T>
{

    graph: T
}

#[cfg(feature = "serde_support")]
#[derive(Serialize)]
pub struct Teststruct<T>
where T: Serialize
{
    graph: T
}

请注意,虽然在此示例中严格限制了where T: Serialize的特征,但在我当前面临的问题中是必需的

因此,以上内容对我来说似乎是不必要的代码重复,尤其是在结构包含更多字段的情况下。我宁愿写这样的东西:

#[cfg(feature = "serde_support")]
use serde::Serialize;

#[cfg_attr(feature = "serde_support", derive(Serialize))]
pub struct Teststruct<T: Node>
where T: Serialize,
      Graph<T>: Serialize + DeserializeOwned
{

    graph: Graph<T>
}

但是,现在,我只能使用功能“ serde_support”进行编译-没有该功能,我显然会得到错误:Serialize在此范围内找不到。

我试图找到类似cfg_attr的特征绑定,但无济于事。

是否有一种优雅的方法来避免代码重复?

2 个答案:

答案 0 :(得分:3)

您可以引入一个新的中间性状MySerialize,因此您始终需要MySerialize而不是Serialize,因此只能在一个地方进行此切换。

可以通过cfg_attr解决派生。

#[cfg(feature = "serde_support")]
use serde::Serialize;

#[cfg(feature = "serde_support")]
pub trait MySerialize : Serialize {}

#[cfg(not(feature = "serde_support"))]
pub trait MySerialize {}

#[cfg_attr(feature = "serde_support", derive(Serialize))]
pub struct Teststruct<T>
    where T: MySerialize
{
    graph: T
}

答案 1 :(得分:0)

或者只是使用条件编译:

#[cfg_attr(feature = "serde_support", derive(Serialize))]
pub struct TestStruct<
    #[cfg(feature = "serde_support")] T: serde::Serialize,
    #[cfg(not(feature = "serde_support"))] T,
> {
    graph: T
}

出于某种原因,您还不能在 where 块中执行此操作,这样看起来会更好。 (每晚 rustc 1.55.0)

相关问题