Уникальные векторные шаблоны больше не поддерживаются

Я понимаю, что Руст находится в движении, но я все равно пытаюсь научиться этому. Я пытаюсь понять, как я мог бы адаптировать следующий пример, который работает с 0,9, в нечто подобное, что работает с 0,10:

fn main() {
    let argv = std::os::args();

    let (first, last) = match argv {
        [_, first_arg, .., last_arg] => (first_arg, last_arg),
        _ => fail!("Error: At least two arguments expected.")
    };

    println!("The first argument was {:s}, \
              and the last argument was {:s}.", first, last); 
}

Когда я строю это с 0.10, я получаю следующую ошибку:

error: couldn't read test.rc: no such file or directory (No such file or directory)
orflongpmacx8:rust pohl_longsine$ rustc test.rs
test.rs:9:9: 9:37 error: unique vector patterns are no longer supported
test.rs:9         [_, first_arg, .., last_arg] => (first_arg, last_arg),
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

Мой вопрос: можно ли по-прежнему использовать сопоставление с образцом в argv, но с другим синтаксисом, или использование оператора сопоставления в argv больше невозможно? Если это первое, что я должен изменить?

1 ответ

Решение

Вы можете все еще соответствовать на ломтиках &[T] и фиксированной длины массивов [T, .. n], так что в этом случае

fn main() {
    let argv = std::os::args();

    let (first, last) = match argv.as_slice() {
        [_, ref first_arg, .., ref last_arg] => (first_arg, last_arg),
        _ => fail!("Error: At least two arguments expected.")
    };

    println!("The first argument was {:s}, \
              and the last argument was {:s}.", *first, *last); 
}

Обратите внимание на добавление refs. argv является ~[~str]т.е. содержимое является собственностью строк ~strкоторые передают право собственности, когда передаются по стоимости как [_, first_arg, .., last_arg] шаблон будет делать. Это незаконно, чтобы переместить собственность из-за заимствованного указателя (как часть &[~str]) так что шаблон будет незаконным. Можно взять в срез (и любой другой шаблон), используя ref ключевое слово, делая first а также last обе ссылки типа &~str,

Можно задаться вопросом, почему *first а также *last разыменования не пытаются переместить ~str из-за &~str, но это потому что println! макрос расширяется по существу &*first а также &*lastэто нормально.

(Мы могли бы также написать => (first_arg.as_slice(), last_arg.as_slice()) одолжить два &~strс прямыми кусочками &strЭто означает, что нам не нужно разыменовывать в println!.)

Другие вопросы по тегам