rust 类型更改结构更新语法的稳定类似物

bqujaahr  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(98)
设置

寻找最简单的解决方案,而改变类型的结构更新语法是不稳定的。我有以下结构:

struct A<T> {
  i1: i32,
  i2: i32,
  pd: PhantomData<T>,
  s: String,
}

字符串

注意事项

实际上,结构体有更多的字段,它们有长的有意义的名称。此外,它们中的一些具有第三方类型和/或表示一些外部资源(例如,第三方资源)。HTTP连接等)。
问题
我必须实现这个函数:

fn into_unit<T>(a: A<T>) -> A<()>;


什么是最简单的方法,而不需要我重复所有的字段?

我的尝试

下面是我对frunk的尝试,但它需要一些破译才能理解,所以它不一定比纯粹的析构方法简单:

fn into_unit<T>(a: A<T>) -> A<()> {
    let a = frunk::into_labelled_generic(a);
    frunk::from_labelled_generic(hlist![field![_, PhantomData::<()>], ...a].sculpt().0)
}

kpbwa7wx

kpbwa7wx1#

您可以将结构体定义 Package 在一个宏中,该宏将生成相应的into_unit实现:

use std::marker::PhantomData;

macro_rules! with_phantom_conversion {
    (struct $name:ident { $($field:ident: $type:ty),* $(,)?}) => {
        struct $name<T> {
            $($field: $type,)*
            pd: PhantomData<T>,
        }

        fn into_unit<T> (other: $name<T>) -> $name<()> {
           $name {
               $($field: other.$field,)*
               pd: PhantomData,
           }
        }
    }
}

with_phantom_conversion! {
    struct A {
        i1: i32,
        i2: i32,
        s: String,
    }
}

fn main() {
    let a: A<i32> = A { i1: 1, i2: 2, s: "foo".to_string(), pd: PhantomData, };
    let _b: A<()> = into_unit (a);
}

字符串
Playground

相关问题