27

教程展示了一些非常基本的模式匹配示例,例如匹配整数以模拟 c 风格的 switch 语句。本教程还展示了如何对元组类型进行基本解构,以及解构结构。

似乎应该可以对向量进行模式匹配,但我无法找出正确的语法,也没有找到任何例子。

例如,在 Haskell 中,您可以轻松地解构列表:

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr func initValue []     = initValue
foldr func initValue (x:xs) = func initValue $ foldr initValue func xs

所以,看一个粗略的翻译,能够做到这一点会很好:

fn foldr<A, B>(func: fn(A, B) -> B,
               initValue: B,
               vals: [A]) -> B {
  alt vals {
    [] { ret initValue; }
    _  {
      let h = vec::head(vals),
          t = vec::tail(vals);
      ret foldr(func, func(initValue, h), t);
    }
  }
}

注意:我知道您可以在这里使用 if 语句,我只是将其用作向量上的模式匹配示例。

这当前返回:

patterns.rs:10:4: 10:5 error: constant contains unimplemented expression type
patterns.rs:10     [] { ret initValue; }
                ^
error: aborting due to previous errors

本教程中有一个用于解构结构(用 定义{ .. })和元组(用 定义)的示例( .. ),因此考虑到它们还包含特殊语法(用 定义),似乎也应该内置对向量的支持[ .. ]

如果我也以错误的方式使用向量,请随时纠正我。

4

2 回答 2

21

您需要切片模式

fn vec_alt<T>(vals: Vec<T>) -> &'static str {
    match vals[..] {
        [a, b] => "two elements",
        [a, b, c] => "three elements",
        _ => "otherwise",
    }
}
于 2019-07-15T11:08:54.100 回答
7

我希望我可以就如何最好地在向量上使用模式匹配提供更一般的建议,但这里是你如何使用它们来测试空向量的方法(至少我认为这就是 Haskell 代码正在做的事情......):

use std;
import std::io::println;

fn main() {
    let empty: [int] = [];
    println(vec_alt(empty));
    println(vec_alt([1,2,3]));
}

fn vec_alt<A>(vals: [A]) -> str {
    alt vals {
        x if x == [] { "empty" }
        _ { "otherwise" }
    }
}

请注意,尝试简单地[]作为参数传递会失败,因为编译器无法推断向量的类型。似乎可以在不首先声明的情况下传递[()](带有nil内部的向量),但该alt语句似乎无法测试头部表达式是否匹配[()](它只是通过默认值)。

总而言之,向量目前看起来有点粗糙。如果您想到 Rust 似乎不支持某些特定用途,开发人员非常愿意接受建议和批评:https ://mail.mozilla.org/listinfo/rust-dev

另请参阅参考手册以获得更正式的定义,以及更多示例以帮助澄清事情:http ://doc.rust-lang.org/doc/rust.html#alternative-expressions

于 2012-02-14T21:27:16.107 回答