Сравнение ржавчины по вектору

tutorial показывает некоторые очень простые примеры сопоставления шаблонов, такие как сопоставление по целому числу для эмуляции оператора switch c-style, В учебнике также показано, как выполнить базовое деструктурирование по типу кортежа и структуры деструктурирования.

Похоже, что должно быть возможно сопоставить соответствие по вектору, но я не могу определить правильный синтаксис для него, и я не нашел его примеров.

Например, в 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

В учебнике по деструктурированию структур (определенному с помощью { .. }) и кортежам (определенному с помощью ( .. )) есть пример, так что кажется, что должна быть встроенная поддержка векторов, так как они также содержат специальный синтаксис (определенный с помощью [ .. ]).

Не стесняйтесь исправлять меня, если я тоже использую векторы.

Ответ 1

Мне хотелось бы дать более общие рекомендации о том, как наилучшим образом использовать сопоставление шаблонов на векторах, но вот как вы можете использовать их для проверки пустых векторов (по крайней мере, я думаю, что то, что делает этот код 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