Rust - 特征绑定取决于功能?
Rust - trait bound depending on feature?
我最近开始使用 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 的东西,但无济于事。
有没有一种优雅的方法来避免代码重复?
你可以引入一个新的中间特征 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
}
或者只使用条件编译:
#[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-每晚)
我最近开始使用 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 的东西,但无济于事。
有没有一种优雅的方法来避免代码重复?
你可以引入一个新的中间特征 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
}
或者只使用条件编译:
#[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-每晚)