使用布尔值检查Rust枚举类型?

6

我希望用户在命令行参数中传递给我编写的 Rust 函数。我知道可以使用 int::from_str(args[1]) 进行转换,但这会返回一个 Option<int>, 这意味着为了将其传递给需要一个 int 的函数(如下面的函数),我必须使用一个 match 语句。但是有 n 个参数时,就有 2^n 种可能性。编写一系列嵌套的 match 语句将是可怕的。如果有一种方法可以像下面那样做就好了:

// will return either Some(int) or None
let start = int::from_str(args[1]), end = int::from_str(args[2]);
if typeof(start) == Some && typeof(end) == Some { 
    println(fmt!("You entered: %d, %d", start, end); 
} else { 
    println("Error with arguments."); 
}

有没有其他的方法能够测试某个枚举成员,除了使用 match
1个回答

7
枚举类型的变体都是相同的类型(在这种情况下,NoneSome(foo)都是Option<int>),因此您实际上要做的是检查startend是哪个变体。幸运的是,Rust提供了几个选项。
直接翻译您的代码将使用start.is_some() && end.is_some()。但是,这需要修改格式字符串为fmt!("You entered: %d, %d", start.get(), end.get()),因为startend不是整数,而是仍然包装在Some(...)变体中。(这种变体测试是必须根据每个枚举单独写的,没有内置函数可以让您执行任何枚举的测试。)
更常见的做法可能会像这样:
// will return either Some(int) or None
let start_opt = int::from_str(args[1]), end_opt = int::from_str(args[2]);
match (start_opt, end_opt) { 
    // only matches if both are Some
    (Some(start), Some(end)) => println(fmt!("You entered: %d, %d", start, end),

    // will match when either (or both) are None
    _                        => println("Error with arguments.");
}

啊,我不知道在match语句中可以使用多个参数。太好了。那么,is_some()方法及其类似的方法需要为任何类型显式编写吗? - limp_chimp
@limp_chimp,没错,在标准库中Option已经定义了.is_some()方法;但是如果你自己定义枚举类型,就不会自动有这样的方法。 - huon
1
@limp_chimp:实际上,如果你看一下is_some的实现,它是!self.is_none(),这等同于match *self { None => true, Some(_) => false }。(但不用担心额外方法调用会影响性能;这些都被标记为#[inline]。) - Chris Morgan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接