Reputation: 11603
I have this code:
let fd = libc::creat(path, FILE_MODE);
if fd < 0 {
/* error */
}
the equivalent in C is shorter:
if ((fd = creat(path, FILE_MODE)) < 0) {
/* error */
}
can I do a similar thing in Rust? I tried to map it to if let
but it looks like handling Option
s.
Upvotes: 3
Views: 134
Reputation: 89016
No, it's not possible by design. let
bindings are one of the two non-expression statements in Rust. That means that the binding does not return any value that could be used further.
Bindings as expressions don't make a whole lot of sense in Rust in general. Consider let s = String::new()
: this expression can't return String
, because s
owns the string. Or what about let (x, _) = get_tuple()
? Would the expression return the whole tuple or just the not-ignored elements? So ⇒ let
bindings aren't expressions.
About the if let
: Sadly that won't work either. It just enables us to test if a destructuring works or to put it in other words: destructure a refutable pattern. This doesn't only work with Option<T>
, but with all types.
If you really want to shorten this code, there is a way: make c_int
easily convertible into a more idiomatic type, like Result
. This is best done via extension trait:
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)
}
}
}
With this you can use if let
in the resulting Result
:
if let Err(fd) = libc::creat(path, FILE_MODE).to_res() {
/* error */
}
Upvotes: 5