0

Rust が流動的であることは理解していますが、とにかくそれを学ぼうとしています。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 で match ステートメントを使用することはできなくなりましたか? 前者の場合、何を変更すればよいですか?

4

1 に答える 1

4

You can still match on slices &[T] and fixed length arrays [T, .. n]. so, in this case,

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); 
}

Note the addition of the refs. argv is ~[~str], i.e. the contents are owned strings ~str, which move ownership when passed by value as a [_, first_arg, .., last_arg] pattern would do. It's illegal to move ownership out from behind a borrowed pointer (like a slice &[~str]) so that pattern would be illegal. One can borrow into the slice (and any other pattern) using the ref keyword, making first and last both references of type &~str.

One might wonder why the *first and *last dereferences aren't trying to move a ~str out from behind a &~str, but it's because the println! macro is expanding to essentially &*first and &*last, which is fine.

(We could also write => (first_arg.as_slice(), last_arg.as_slice()) to borrow the two &~strs straight to string slices &str, which then means we don't need to dereference in the println!.)

于 2014-04-05T00:04:28.250 に答える