Уникальные векторные шаблоны больше не поддерживаются
Я понимаю, что Руст находится в движении, но я все равно пытаюсь научиться этому. Я пытаюсь понять, как я мог бы адаптировать следующий пример, который работает с 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);
}
Обратите внимание на добавление ref
s. 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!
.)