2014-04-04 1 views
0

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

ответ

4

Вы все еще можете найти на кусочках &[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); 
} 

Обратите внимание на добавление ref с. То есть ~[~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 S прямо в строковые ломтиков &str, который затем означает, что мы не должны разыменованием в println!.)

+0

Спасибо за такой ясный и полный ответ. – pohl