2016-07-07 9 views
3

私はこのコードを持っている:変数assignentとifを組み合わせることはできますか?

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

同等のCでは短いです:

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

私はルーストに同様のことを行うことができますか? if letにマップしようとしましたが、Optionのように見えます。

答えて

5

いいえ、これは設計上可能ではありません。 letバインディングは、錆の中でone of the two non-expression statementsです。つまり、バインディングはそれ以上使用できる値を返しません。

一般的に、表現としてのバインディングは、錆の意味を全体的に大して意味するものではありません。 let s = String::new()を検討してください:sが文字列を所有しているため、この式はStringを返しません。またはlet (x, _) = get_tuple()はどうですか?式がタプル全体を返すか、無視されない要素だけを返しますか? ⇒letバインディングは式ではありません。

についてif let:悲しいことに、どちらもうまくいきません。それは、単に破壊の仕組みが働いているかどうかをテストしたり、言い換えると、再現可能なパターンを破壊することができます。これはOption<T>で動作するだけでなく、すべてのタイプで動作します。


あなた本当には、このコードを短くしたい場合は、方法があります:Resultのように、より多くの慣用的なタイプにc_intを簡単に転換します。これは、最高の拡張性形質を介して行われます。これにより

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

は、あなたがたResultif letを使用することができます。あなたにも `Result`を返すと、すぐにエラーを返すようにしたい場合は

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

をまたは、単に 'let fd = try!(libc :: creat(...));' –

関連する問題