3

所以,我之前问过这个问题:

有人可以帮我比较在这个特定示例(IP 地址表达式)中使用 F# 而不是 C# 吗?

我正在查看发布的代码,我想知道是否可以编写此代码而不会产生警告:

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

是否可以为 match _ 模式做点什么?不添加诸如活动模式之类的东西?我想保持代码尽可能简单......我可以在不大幅更改此代码的情况下做到这一点吗?

注意:警告如下

警告 此表达式的模式匹配不完整。例如,值 '[|_; _; _; _; _|]' 可能表示模式未涵盖的情况。

4

3 回答 3

5

你可以试试

#nowarn "25"

在偏函数之前。

但是,您当然要禁用警告,我认为这会为整个文件关闭它。我记得看到过一种方法可以仅对文件的一部分禁用警告,但我现在找不到它。

还有编译器选项--nowarn:25,但这更糟糕,因为它适用于整个项目。


要以正确的方式执行此操作,您需要将两行替换为三行:

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 地址(由四个用“.”分隔的子字符串组成),您可以定义一个匹配的活动模式:

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 回答