3

そこで、以前こんな質問をしました。

この特定の例 (IP アドレス式) で C# よりも F# を使用して比較するのを手伝ってくれる人はいますか?

投稿されたコードを見ていて、警告を生成せずにこのコードを記述できるかどうか疑問に思っていました。

let [|a;b;c;d|] = s.Split [|'.'|]
IP(parseOrParts a, parseOrParts b, parseOrParts c, parseOrParts d)

match _ pattern ot ignore に対して何かできることはありますか? アクティブ パターンのようなものを追加せずに? コードをできるだけシンプルに保ちたい...このコードを大幅に変更せずにこれを行うことはできますか?

注: 警告は次のとおりです。

警告 この式ではパターン一致が不完全です。たとえば、値 '[|_; _; _; _; _|]' は、パターンでカバーされていないケースを示している可能性があります。

4

3 に答える 3

5

あなたは試すかもしれません

#nowarn "25"

部分関数の前。

しかし、もちろん、警告を無効にしているので、これによりファイル全体が無効になると思います。ファイルの一部だけの警告を無効にする方法を見た覚えがありますが、今は見つかりません。

コンパイラ オプションもあります--nowarn:25が、プロジェクト全体に適用されるため、これはさらに悪いことです。


これを正しい方法で行うには、2 行を 3 行に置き換える必要があります。

match Array.map parseOrParts (s.Split [|'.'|]) with
| [|a;b;c;d|] -> IP(a,b,c,d)
| _ -> failwith "Oh no!"   // preferably, your exception of choice goes here.
于 2010-05-13T18:20:37.977 に答える
4

この警告は、String.Split 呼び出しの後に正確に 4 つの要素がない場合、MatchFailureExceptionが発生することを示していることに注意してください。

他の人が言ったように、警告を取り除く最良の方法は

match s.Split(...) with
| [| a; b; c; d |] -> blah(a,b,c,d)
| _ -> raise <| new Exception("Expected exactly 4 parts") // or whatever
于 2010-05-13T18:40:27.813 に答える
3

「アクティブパターンなどを追加せずに」と書いたことは知っていますが、とにかくそれらを使用するソリューションを投稿します。これらはこのような問題に最適であり、F# のかなり標準的な機能であるため、回避したい理由はまったくありません。ここでアクティブ パターンを使用すると、コードが確実に読みやすくなります。

(もしあなたが F# の初心者なら、単純な解決策から始めたい理由は理解できますが、とにかく、これは最終的にアクティブ パターンを学習する良い動機になるかもしれません :-)、それらは見た目ほど難しくありません。初見)

文字列が IP アドレスとしてフォーマットされている場合に一致するアクティブなパターンを定義できます (「.」で区切られた 4 つの部分文字列で構成されます)。

let (|IPString|_|) (s:string) =
  match s.Split('.') with
  | [|a;b;c;d|] -> Some(a, b, c, d) // Returns 'Some' denoting a success
  | _ -> None                       // The pattern failed (string was ill-formed)

match s with 
| IPString(a, b, c, d) ->  
    // Matches if the active pattern 'IPString' succeeds and gives
    // us the four parts of the IP address (as strings)
    (parseOrParts a, parseOrParts b, parseOrParts c, parseOrParts d)
| _ -> failwith "wrong format"

これは、文字列が正しくない場合に対処できる適切な方法です。もちろん、失敗しないバージョンを定義することもできます (文字列の形式が正しくない場合は、たとえば 0.0.0.0 を返します)。

// This active pattern always succeeds, so it doesn't include the "|_|" part 
// in the name. In both branches we return a tuple of four values.
let (|IPString|) (s:string) =
  match s.Split('.') with
  | [|a;b;c;d|] -> (a, b, c, d)
  | _ -> ("0", "0", "0", "0")

let (IPString(a, b, c, d)) = str
(parseOrParts a, parseOrParts b, parseOrParts c, parseOrParts d)

ほとんどの人は、これがより読みやすいことに同意すると思います。もちろん、単一目的のスクリプトのためだけに何か単純なものを書きたい場合は、警告を無視するだけでかまいませんが、より大きなものについては、アクティブなパターンを好みます。

于 2010-05-13T19:27:24.683 に答える