【问题标题】:Matching parameterized types in Rust在 Rust 中匹配参数化类型
【发布时间】:2014-12-04 03:39:56
【问题描述】:

在一个 Rust 程序中,我有一个用例,我想打印一个数字或管道分隔的数字向量,因此这个简单的包装枚举:

pub enum OneOrMore<T> {
  One(T),
  More(Vec<T>)
}

效果很好。但是后来我想把格式逻辑移到OneOrMore类型中,所以我尝试了:

impl<T: Show> Show for OneOrMore<T> {
  fn fmt(&self, f: &mut Formatter) -> Result {
    match self {
      One(x) => x.fmt(f),
      More(xs) => /* vec_join(xs, "|") or whatever */,
    }
  }
}

由于impl 是参数化的,因此它需要One&lt;T&gt;,但我的代码描述的是One&lt;_&gt;。问题是我无法弄清楚将类型参数放在匹配臂内的位置。 syntax guide 没有给出参数化类型匹配的示例,fmt 本身不接受类型参数,而且我所有的盲目猜测(One(x: T)One&lt;T&gt;(x) 等)都不是有效的 Rust。有什么想法我应该指出火柴臂的类型吗?

【问题讨论】:

    标签: types pattern-matching rust


    【解决方案1】:

    match 表达式中,self 的类型为&amp;OneOrMore&lt;T&gt;,但手臂图案的类型为OneOrMore&lt;T&gt;;即您在参考上匹配,但手臂不是参考。

    您可以将模式更改为引用:

    impl<T: Show> Show for OneOrMore<T> {
      fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
          &One(ref x) => x.fmt(f),
          &More(ref xs) => /* ... */,
        }
      }
    }
    

    或者您可以通过取消引用 self 来避免重复 &amp;

    impl<T: Show> Show for OneOrMore<T> {
      fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match *self {
          One(ref x) => x.fmt(f),
          More(ref xs) => /* ... */,
        }
      }
    }
    

    请注意,在这两种情况下,我们都需要在xxs 绑定上添加ref 关键字,以创建对OneOrMore 内部的引用。换句话说,没有refxxs 将是T 类型;对于ref,它们的类型为&amp;T。如果没有ref,编译器会抱怨我们试图将一个值移出OneOrMore,这是不允许通过借用的。

    【讨论】:

    • 谢谢,这次我完全误解了编译器错误。
    • 标准 Rust 样式是 match *foo { Bar =&gt; () } 而不是 match foo { &amp;Bar =&gt; () },顺便提一下,尽管对于匹配的表达式是元组的情况,例如 match (self, other) { (&amp;Foo, &amp;Foo) =&gt; () },这不能保持正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    相关资源
    最近更新 更多