是否可以使用功能标志进行条件特征继承(例如发送+同步)?

Azu*_*ker 5 rust

在库中,人们可能希望根据功能标志将特征的实现限制为线程安全。这有时涉及改变特质继承。但是,特征继承边界上不允许使用属性。常见的解决方法是复制特征:

#[cfg(not(feature = "thread_safe"))]
pub trait MyTrait {
    fn foo();
}

#[cfg(feature = "thread_safe")]
pub trait MyTrait: Send + Sync {
    fn foo();
}
Run Code Online (Sandbox Code Playgroud)

可以通过使用宏来减少重复的代码(见下文),但这可能会影响 IDE 体验。有没有更好的方法来实现条件性状遗传?

macro_rules! my_trait {
    ($($bounds:ident),*) => {
        pub trait MyTrait where $(Self: $bounds),* {
            fn foo();
        }
    };
}

#[cfg(not(feature = "thread_safe"))]
my_trait!();
#[cfg(feature = "thread_safe")]
my_trait!(Send, Sync);
Run Code Online (Sandbox Code Playgroud)

Dav*_*ret 2

根据对Maybe-sync箱(您可能希望根据您的情况使用它)的查看,我发现可以通过执行以下操作来做到这一点:

#[cfg(feature = "thread_safe")]
mod sync {
  pub use core::marker::Sync as MaybeSync;
  pub use core::marker::Send as MaybeSend;
}

#[cfg(not(feature = "thread_safe"))]
mod sync {
  pub trait MaybeSync {}
  impl<T> MaybeSync for T where T: ?Sized {}
  pub trait MaybeSend {}
  impl<T> MaybeSend for T where T: ?Sized {}
}

// then to use
use sync::MaybeSend;
use sync::MaybeSync;

pub trait MyTrait: MaybeSend + MaybeSync {
  fn foo();
}
Run Code Online (Sandbox Code Playgroud)