我有这段代码:
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。
答案 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 */
}