[英]Implementing a trait for multiple types at once
我有两个结构和一个特征:
struct A {
x: u32,
}
struct B {
x: u32,
}
trait T {
fn double(&self) -> u32;
}
我想使用x
为两个结构实现T
。
有没有办法写出类似的东西
impl T for A, B {
fn double(&self) -> u32 {
/* ... */
}
}
如果可能,我不想使用宏。
为许多具体类型实现一次 trait 的唯一方法是为所有已经实现另一个 trait 的类型实现一个 trait。
例如,您可以实现一个标记特征Xed
,然后:
impl<T> Double for T
where
T: Xed,
{
fn double(&self) {
/* ... */
}
}
然而,Rust 有原则的泛型。 您在之前的实现中唯一了解T
的是T
实现了Xed
trait
,因此您可以使用的唯一关联类型/函数是来自Xed
类型/函数。
trait 不能公开字段/属性,只能公开相关的类型、常量和函数,因此Xed
需要x
的 getter(不需要称为x
)。
如果您希望依赖代码的句法(而非语义)属性,请使用宏。
创建宏也可以解决您的问题:
struct A {
x: u32,
}
struct B {
x: u32,
}
trait T {
fn double(&self) -> u32;
}
macro_rules! impl_T {
(for $($t:ty),+) => {
$(impl T for $t {
fn double(&self) -> u32 {
self.x * 2
}
})*
}
}
impl_T!(for A, B);
fn main() {}
使用duplicate
属性宏,您可以执行以下操作:
use duplicate::duplicate;
#[duplicate(name; [A]; [B])]
impl T for name {
fn double(&self) -> u32 {
self.x * 2
}
}
这将扩展为两个结构的两个相同的实现。 我知道你说你不想使用宏,但我认为这意味着你不想推出自己的宏,所以我认为这是一个很好的妥协。
您还可以使用duplicate
来避免重复您的结构定义:
use duplicate::duplicate;
#[duplicate(name; [A]; [B])]
struct name {
x: u32,
}
或者,如果您出于某种原因需要两个具有相同实现的相同结构(此时我们应该开始质疑为什么我们需要两个结构:D):
use duplicate::duplicate;
#[duplicate(
mod_name struct_name;
[a] [A];
[b] [B];
)]
mod mod_name {
pub struct name {
x: u32,
}
impl T for name {
fn double(&self) -> u32 {
self.x * 2
}
}
}
mod a;
mod b;
pub use self::{a::*, b::*};
由于结构的内部是相同的/共享公共组件,因此您应该将它们提取到公共结构中并将公共部分嵌入回父结构中。 公共结构将具有特征的“复杂”实现,然后父结构的特征实现将委托给公共实现:
trait T {
fn double(&self) -> u32;
}
struct A {
common: Common,
}
impl T for A {
fn double(&self) -> u32 {
self.common.double()
}
}
struct B {
common: Common,
}
impl T for B {
fn double(&self) -> u32 {
self.common.double()
}
}
struct Common {
x: u32,
}
impl T for Common {
fn double(&self) -> u32 {
self.x * 2
}
}
任何更好的代码都需要更改语言。 两种可能的路径:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.