2017-02-20 23 views
9

私は文字列は「$」が含まれているかどうかを確認したいと「$」の後に何かがある場合:マッチガードと同じマッチアームで2つのパターンを組み合わせることは可能ですか?

fn test(s: String) { 
    match s.find('$') { 
     None | (Some(pos) if pos == s.len() - 1) => { 
      expr1(); 
     } 
     _ => { expr2(); } 
    } 
} 

しかし、それはコンパイルされません:

私はこのコードを試してみました

error: expected one of `)` or `,`, found `if` 

それは1試合腕にNoneSomeを結合することは不可能ですか?

もしそうなら、expr1()を別の機能に移動することを除いて、複製しない簡単な方法がありますか?

答えて

7

それはマッチガード(ifブツ)が1つのパターンのみの代替(|記号で区切られたもの)に適用させることは不可能です。 1つの腕に1つのマッチガードがあり、それはその腕のすべてのパターンに適用されます。

ただし、特定の問題にはさまざまな解決策があります。例:

if s.find('$').map(|i| i != s.len() - 1).unwrap_or(false) { 
    expr2(); 
} else { 
    expr1(); 
} 
+3

これはうまくいきますが、 '$'はASCIIで1バイトを占めるという事実に依存しています。より一般的な解決法は、['char :: len_utf8'](https://doc.rust-lang.org/std/primitive.char.html#method.len_utf8)を使用するかもしれません:' i!= s.len() - 'c'.len_utf8() '。 – Shepmaster

+2

私はゴルフコード '' s.chars()。skip_while(| i | i!= '$')。skip(1).next()。is_some() 'がインデックスの計算よりはるかに明確です。 –

関連する問題