首页 > 解决方案 > 在实现特征以访问许多结构中的字段时,如何避免代码重复?

问题描述

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

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

标签: rustcomposition

解决方案


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

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());
}


推荐阅读