Сопоставление ржавчины с вектором - PullRequest
11 голосов
/ 14 февраля 2012

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

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

Например, в Haskell вы можете легко деструктурировать список:

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

Так что, глядя на грубый перевод, было бы неплохо иметь возможностьto do:

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

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

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

Ответы [ 2 ]

7 голосов
/ 15 февраля 2012

Хотелось бы дать более общие советы о том, как наилучшим образом использовать сопоставление с образцом для векторов, но вот как вы можете использовать их для проверки пустых векторов (по крайней мере, я думаю , что это тот код на Haskelldo ...):

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 # альтернативные выражения

1 голос
/ 15 июля 2019

Вам нужно это https://doc.rust -lang.org / reference / patterns.html # slice-pattern

fn vec_alt<A>(vals: Vec<A>) -> str {
    match vals[..] {
        [] => { "empty" }
        _ => { "otherwise" }
    }
}
...