Rust匹配不起作用

时间:2014-07-29 01:32:31

标签: match rust

我正在做一些生锈的简单的东西...只是触摸你知道的一些地方。

所以我正在玩命令行参数,我不能超越这个:

use std::os::args;

fn main(){

    let arg1 = args().get(1).to_str();

    let help_command = "help";

    if args().len() == 1 {
            println!("No arguments.");
    }

    else if args().len() == 2 {

            match arg1 {
                    help_command => println!("Do ..."),
                    _    => println!("no valid argument")
            }

    }

}

我无法编译......错误是:

main.rs:17:4: 17:5 error: unreachable pattern
main.rs:17                      _    => println!("no valid argument")
                                ^
error: aborting due to previous error

另外,我每晚都在使用Rust 0.11.0。

谢谢

编辑:另外,如果我采用这种方法:

match arg1 { 
    "help" => { /* ... / }, 
    _ => { / ... */ }, 
}

它引发了另一个错误:

"error: mismatched types: expected collections::string::String but found &'static str         (expected struct collections::string::String but found &-ptr) "

1 个答案:

答案 0 :(得分:5)

你不能在Rust的match模式上使用变量。代码被解释为绑定arg1上的任何值作为名为help_command的新变量,因此catch-all模式永远不会匹配。

您可以使用文字字符串匹配arg1

match arg1 {
    "help" => { /* ... */ },
    _      => { /* ... */ },
}

或者使用警卫:

match arg1 {
    command if command == help_command => { /* ... */ },
    _ => { /* ... */ }
}

如果您担心直接使用字符串的类型安全和/或重复,可以将命令解析为枚举:

enum Command {
    HelpCommand,
    DoStuffCommand
}

fn to_command(arg: &str) -> Option<Command> {
    match arg {
        "help"     => Some(HelpCommand),
        "do-stuff" => Some(DoStuffCommand),
        _          => None,
    }
}

Working example

更新(感谢@ChrisMorgan):也可以使用静态变量:

static HELP: &'static str = "help";

match arg1 {
    HELP => { /* ... */ },
    _ => { /* ... */ },
}

关于问题编辑中报告的错误:Rust有两种字符串:&str (string slice)String (owned string)。主要区别在于第二种是可生长的并且可以移动。请参阅链接以更好地理解区别。

您遇到的错误是由于字符串文字("foo")的类型为&str,而std::os::args() is a Vec of String。解决方案很简单:使用.as_slice()上的String方法从中获取切片,并将其与文字进行比较。

在代码中:

match arg1.as_slice() {
    "help" => { /* ... */ },
    _      => { /* ... */ },
}