【问题标题】:How to create a value with an associated type using a normal struct constructor?如何使用普通结构构造函数创建具有关联类型的值?
【发布时间】:2018-03-24 00:37:18
【问题描述】:

我正在尝试创建一个宏,该宏使用 P::Child from struct P where P: Parent<Child = T> 初始化结构 T

macro_rules! init {
    ($t:tt, { $( $k:ident =>  $v:expr ),* }) => {
        <$t as Parent>::Child {
            $( $k: $v ),*
        }
    };
}

此宏将 props 作为映射传递给结构的给定构造函数。展开后,它看起来像这样:

#[derive(Debug)]
struct Apple {
    a: i32
}

trait Parent {
    type Child;
}

struct Mango;

impl Parent for Mango {
    type Child = Apple;
}

fn main() {
    let a = <Mango as Parent>::Child {
        a: 4
    };
    println!("{:?}", a);
}

编译这个有错误:

error: expected one of `.`, `::`, `;`, `?`, or an operator, found `{`
  --> src/main.rs:25:38
   |
25 |     let a = <Mango as Parent>::Child {
   |                                      ^ expected one of `.`, `::`, `;`, `?`, or an operator here

我已经创建了一个宏来以类似的方式初始化一个结构,但我无法使用关联类型来完成它。我认为编译器由于某种原因不支持它。尽管如此,我还是想用这样的 API 创建一个宏。

我该如何解决这个问题?

Link to Playground

【问题讨论】:

    标签: rust


    【解决方案1】:

    像这样:

    macro_rules! init {
        ($t:ty, { $( $k:ident =>  $v:expr ),* }) => {
            {
                type T = <$t as Parent>::Child;
                T {
                    $( $k: $v ),*
                }
            }
        };
    }
    

    我的假设是这是解析器的限制,而不是编译器的类型分析。

    【讨论】:

      【解决方案2】:

      我认为不可能初始化关联类型。

      你可以做的也许是让Child: KK 是一个具有一些已知构造函数(::new 等...)的特征,然后调用该构造函数。

      或者,您也可以直接初始化 T 而不是 Child

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-02
        • 1970-01-01
        • 1970-01-01
        • 2015-10-25
        • 1970-01-01
        • 2016-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多