【问题标题】:How do I avoid code duplication when implementing a trait to access a field in many structs? [duplicate]在实现特征以访问许多结构中的字段时,如何避免代码重复? [复制]
【发布时间】:2021-10-04 16:38:42
【问题描述】:

我正在尝试实现一个特征以从外部结构中获取内部结构。我有许多外部结构,并希望避免代码重复。我需要单独实现该方法还是有更好的方法通过组合来实现?它无法编译,但这是我正在尝试做的一个最小示例:

struct Inner {
    id: i32,
}

struct Outer1 {
    inner: Inner,
    something: i32,
}

struct Outer2 {
    inner: Inner,
    something_different: String,
}

trait GetInner {
    fn id(&self) -> i32 {
        self.inner.id
    }
}

impl GetInner for Outer1 {}
impl GetInner for Outer2 {}

fn main() {
    let inner = Inner { id: 1 };
    let outer1 = Outer1 {
        inner: inner,
        something: 2,
    };

    outer.id()
}
error[E0425]: cannot find value `outer` in this scope
  --> src/main.rs:31:5
   |
31 |     outer.id()
   |     ^^^^^ help: a local variable with a similar name exists: `outer1`

error[E0609]: no field `inner` on type `&Self`
  --> src/main.rs:17:14
   |
15 | / trait GetInner {
16 | |     fn id(&self) -> i32 {
17 | |         self.inner.id
   | |              ^^^^^
18 | |     }
19 | | }
   | |_- type parameter 'Self' declared here

【问题讨论】:

    标签: rust composition


    【解决方案1】:

    您可以使用声明性宏来实现特征:

    struct Inner {
        id: i32,
    }
    
    struct Outer1 {
        inner: Inner,
        something: i32,
    }
    
    struct Outer2 {
        inner: Inner,
        something_different: String,
    }
    
    trait GetInner {
        fn id(&self) -> i32;
    }
    
    macro_rules! get_inner_impl {
        ($($outer:ty)*) => ($(
            impl GetInner for $outer {
                fn id(&self) -> i32 {
                    self.inner.id
                }
            }
        )*)
    }
    
    get_inner_impl! { Outer1 Outer2 }
    
    fn foo(outer1: Outer1) {
        println!("{}", outer1.id());
    }
    
    fn bar(outer2: Outer2) {
        println!("{}", outer2.id());
    }
    
    

    【讨论】:

      猜你喜欢
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多