【问题标题】:Check type of Rust enum with a boolean?用布尔值检查 Rust 枚举的类型?
【发布时间】:2013-06-05 13:48:07
【问题描述】:

我希望用户将命令行参数传递给我用 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 之外的枚举成员中的哪个成员?

【问题讨论】:

    标签: enums match rust


    【解决方案1】:

    枚举的变体都是相同的类型(在这种情况下,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.");
    }
    

    【讨论】:

    • 啊,我不知道你可以在一场比赛中做多个参数。那太棒了。那么,我认为is_some() 方法及其类似方法需要为那里的任何类型显式编写?
    • @limp_chimp,正确,在标准库的Option 上定义了.is_some();但如果你定义自己的枚举,就不会自动出现这样的方法。
    • @limp_chimp: 实际上,如果您查看is_some 的实现,它是!self.is_none(),即match *self { None => true, Some(_) => false }。 (但不要担心额外的方法调用会受到影响;这些都标记为#[inline]。)
    猜你喜欢
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 2019-12-30
    • 2011-05-10
    • 2018-10-31
    • 2019-03-03
    • 1970-01-01
    相关资源
    最近更新 更多