我可以将变量assignent与if结合使用吗?

时间:2016-07-07 06:47:39

标签: rust

我有这段代码:

let fd = libc::creat(path, FILE_MODE);
if fd < 0 {
    /* error */
}

C中的等价物更短:

if ((fd = creat(path, FILE_MODE)) < 0) {
    /* error */
}

我可以在Rust做类似的事情吗?我尝试将其映射到if let,但它看起来像处理Option s。

1 个答案:

答案 0 :(得分:5)

,设计无法实现。 Rust中let绑定为one of the two non-expression statements。这意味着绑定不会返回任何可以进一步使用的值。

作为表达式的绑定在Rust中通常没有多大意义。考虑let s = String::new():此表达式无法返回String,因为s拥有该字符串。或者let (x, _) = get_tuple()呢?表达式会返回整个元组还是只返回未被忽略的元素?所以⇒let绑定不是表达式。

关于if let:遗憾的是,它也不会起作用。它只是让我们能够测试一个解构是否有效还是换句话说:构建一个可反复的模式。这不仅适用于Option<T>,而是适用于所有类型。

如果确实希望缩短此代码,可以采用以下方法:将c_int轻松转换为更惯用的类型,例如Result。这最好通过扩展特性来完成:

trait LibcIntExt {
    fn to_res(self) -> Result<u32, u32>;
}

impl LibcIntExt for c_int {
    fn to_res(self) -> Result<u32, u32> {
        if self < 0 {
            Err(-self as u32)
        } else {
            Ok(self as u32)
        }
    }
}

有了这个,您可以在结果if let

中使用Result
if let Err(fd) = libc::creat(path, FILE_MODE).to_res() {
    /* error */
}