[英]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.