以该代码为例,如何检查输入是否为null?类似的代码抛出nullreference异常
let private Method ( str:string) : string =
let a = str
a.[a.Length-1]
答案 0 :(得分:1)
尽管isNull
是一个非常简单的答案,并且非常有效,但我认为与其他几个人一起玩会很有趣,因为F#很有趣:)
首先让我们设置一个小功能来快速测试结果
open System
let test f a =
try
printfn "Input %A, output %A" a (f a)
printfn "Input %A, output %A" "" (f "")
printfn "Input %A, output %A" null (f null)
with
| :? Exception as ex -> printfn "%s" ex.Message
我们的第一个功能就是建立基线。
引发异常
//string -> string
let getLast1 ( s:string) : string = s.[s.Length-1] |> string
printfn "=== getLast1 ==="
test getLast1 "bing"
=== getLast1 ===
输入“ bing”,输出“ g”
索引超出了数组的范围。
下一个使用if
检查该值,如果不是有效值,则返回一个空字符串。
返回空字符串
//string -> string
let getLast2 ( s:string) : string =
if (String.IsNullOrEmpty s) then ""
else s.[s.Length-1] |> string
printfn "=== getLast2 ==="
test getLast2 "bing"
=== getLast2 ===
输入“ bing”,输出“ g”
输入“”,输出“”
输入,输出“”
我们至少现在要执行所有路径。
让我们尝试一种更实用的方法:
使用模式匹配返回option
//string -> string option
let getLast3 (s:string) =
match s with
| null -> None
| _ ->
match (s.ToCharArray()) with
| [||] -> None
| [|x|] -> Some x
| xs -> Array.tryLast xs
|> Option.map string
printfn "=== getLast3 ==="
test getLast3 "bing"
=== getLast3 ===
输入“ bing”,输出一些“ g”
输入“”,输出// //注意 实际上是 None
。
输入,输出 // //注意 实际上是 None
。
那行得通,但这不是最容易阅读的功能。还算不错,但是如果我们尝试将其分解怎么办。
组合功能
//'a -> 'a option
let sanitize x = if (isNull x) then None else Some(x)
//string -> char[]
let toCharArray (s:string) = s.ToCharArray()
//'a[] option -> 'a option
let last xs =
xs |> Option.map Array.tryLast //tryLast returns an 'a option
|> Option.flatten // turns 'a option option to a' option
现在我们有了构建块,我们可以构建新的最后一个函数:
//string -> string option
let getLast4 s =
s |> sanitize
|> Option.map toCharArray
|> last
|> Option.map string
printfn "=== getLast4 ==="
test getLast4 "bing"
=== getLast4 ===
输入“ bing”,输出一些“ g”
输入“”,输出// //注意 实际上是 None
。
输入,输出// //注意 实际上是 None
。
说实话getLast2
可能还不错。如果我发现自己正在检查空字符串,则希望从Some
返回None
或if
。我只是想展示如何从null
转向使用内置的Array
函数。