首页 > 解决方案 > 函数中泛型类型的访问字段

问题描述

在过去的 4 天里,我一直在试图弄清楚这一点,但我真的被困住了。基本上我有大量类似的结构,都包含一个特定的字段。我们称它为datau32 类型:

struct A {
    data: u32,
}

struct B {
    data: u32
}

...

struct N {
    data: u32
}

我需要做的是在这些结构之外编写一个函数,它采用泛型类型(即,这些结构中的任何一个)对字段执行一些操作并返回值。基本上是这样的:

fn some_manipulation<T>(st: &T) -> u32 {
    st.data * 10
}

就目前而言,这是不可能的,因为datatype 上没有字段T。另一件事是我无法修改结构。有没有明智的方法来实现这一目标?

标签: rust

解决方案


因此,正如@Netwave指出的那样,要使其工作,您需要一个some_manipulation用于访问该data字段的特征,但要为所有类型实现此特征,您可以使用自定义宏。

操场

我将我的宏定义为如下所示impl_BorrowData!{u32, [A, B, N]}(其中第一个参数是data字段类型,然后是结构列表,但宏足够灵活,你可以让它看起来像你想要的那样。

trait BorrowData {
    type Output;
    fn borrow_data(&self) -> &Self::Output;
}

macro_rules! impl_BorrowData {
    ($out:ty, [$($t:ty),+]) => {
        $(impl BorrowData for $t {
            type Output = $out;
            fn borrow_data(&self) -> &Self::Output {
                &self.data
            }
        })*
    }
}

impl_BorrowData!{u32, [A, B, N]} // first the output type <u32>, then names of structs

fn some_manipulation<T: BorrowData<Output=u32>>(st: &T) -> u32 {
    st.borrow_data() * 10
}

fn main() {
    let a = A { data: 2 };
    println!("{}", some_manipulation(&a));
    let b = B { data: 50 };
    println!("{}", some_manipulation(&b));
}

推荐阅读