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

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" }
    }
}

[]コンパイラはベクトルの型を推測できないため、単純に引数として渡そうとすると失敗することに注意してください。最初に宣言せずに[()](内部を含むベクトル)を渡すことは可能であるように見えますが、ステートメントは head 式が一致するかどうかをテストすることができないようです(単にデフォルトにフォールスルーします)。nilalt[()]

全体として、現時点ではベクトルは少し荒いように見えます。Rust がサポートしていないように思われる特定の用途がある場合、開発者は提案や批判に対して非常にオープンです: https://mail.mozilla.org/listinfo/rust-dev

また、より正式な定義についてはリファレンス マニュアルを参照してください

于 2012-02-14T21:27:16.107 に答える