2016-07-07 6 views
3

Ich habe diesen Code:Kann ich variable Zuweisung mit einem if kombinieren?

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

das Äquivalent in C kürzer:

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

kann ich eine ähnliche Sache in Rust zu tun? Ich habe versucht, es auf abzubilden, aber es sieht aus wie Handhabung Option s.

Antwort

5

Nein, es ist nicht durch das Design möglich. let Bindungen sind one of the two non-expression statements in Rust. Das bedeutet, dass die Bindung keinen Wert zurückgibt, der weiter verwendet werden könnte.

Bindungen als Ausdrücke machen in Rust im Allgemeinen keinen Sinn. Betrachten Sie let s = String::new(): Dieser Ausdruck kann String nicht zurückgeben, da s die Zeichenfolge besitzt. Oder was ist mit let (x, _) = get_tuple()? Würde der Ausdruck das ganze Tupel oder nur die nicht ignorierten Elemente zurückgeben? Also ⇒ let Bindings sind keine Ausdrücke. Die : Leider funktioniert das auch nicht. Es erlaubt uns nur zu testen, ob eine Destrukturierung funktioniert oder anders ausgedrückt: ein widerlegbares Muster zu destrukturieren. Dies funktioniert nicht nur mit Option<T>, sondern mit allen Typen.


Wenn Sie wirklich diesen Code verkürzen wollen, gibt es eine Möglichkeit: c_int leicht umwandelbar in eine idiomatische Art machen, wie Result. Dies geschieht am besten über Erweiterung Zug getan:

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) 
     } 
    } 
} 

Damit Sie if let in der resultierenden Result verwenden können:

if let Err(fd) = libc::creat(path, FILE_MODE).to_res() { 
    /* error */ 
} 
+0

Oder wenn Sie einen 'Result' zurückkehren, wie gut und wollen Fehler sofort zurück, einfach 'lass fd = versuchen! (libc :: creat (...));' –

Verwandte Themen