9

我习惯用 C# 编写这样的代码:

SomeObj obj;
try{
    // this may throw SomeException
    obj = GetSomeObj();
}catch(SomeException){
    // Log error...
    obj = GetSomeDefaultValue();
}

obj.DoSomething();

这是我在 F# 中翻译它的方式(obj 是一个列表):

let mutable obj = []
try
    obj <- getSomeObj
with
    | ex ->
        // Log ex
        obj <- getSomeDefaultValue

doSomething obj

有什么方法可以在不使用可变变量的情况下在 F# 中执行此操作?在 F# 中是否有更“优雅”的方式来处理这种情况?

谢谢!

4

2 回答 2

20

F#-ish 方式是在两个分支中返回相同类型的表达式:

let obj =
    try
        getSomeObj()
    with
    | ex ->
        // Log ex
        getSomeDefaultValue()

doSomething obj

在 F# 中,您可以使用option类型来处理异常。当没有明显的默认值时,这是一个优势,并且编译器会强制您处理异常情况。

let objOpt =
    try
        Some(getSomeObj())
    with
    | ex ->
        // Log ex
        None

match objOpt with
| Some obj -> doSomething obj
| None -> (* Do something else *)
于 2013-04-08T14:14:12.627 回答
8

将此逻辑包装在函数中...

let attempt f = try Some(f()) with _ -> None
let orElse f = function None -> f() | Some x -> x

...它可能是:

attempt getSomeObj |> orElse getSomeDefaultValue
于 2013-04-08T14:56:15.870 回答