2010-07-12 71 views
3

我想写一个函数,其中只有两个方法调用(方法是单元 - >单元)应该有一个特定的异常处理。这样的行为应该是:
- 如果抛出一个异常,整个函数结束
- 该功能,否则

推移(异常处理程序之外),起初我还以为我可以用与包裹语句的功能在一个try/with块和一个continuation中,但是当然这个continuation会在块内被调用......我可能会将这些语句包装在一个函数中,并使用返回值来表示成功/失败,但是这看起来很笨重我比较下面的C#代码,这正是我想要在F#中实现的。

部分功能的F#异常处理

SomeType MyMethod(string x) 
{ 
    ... 
    try 
    { 
     foo(); 
     bar(); 
    } 
    catch(SomeException) 
    { 
     return null; 
    } 
    ... 
    return ...; 
} 

回答

4

像这样的事情?

// f <- foo(); bar(); etc... 
// k <- unprotected continuation 
let runProtected f k = 
    if try f(); true with _ -> false 
    then k() 
    else null 

// sample from the question 
let runProtected() = 
    if try 
     foo(); bar(); 
     true 
     with _ -> 
     false 
    then unprotected() 
    else null 
+0

我认为这是尽可能接近我想要做的事情,尽管我认为在这种情况下缺乏更好的控制在命令式编程的控制流程上是一个障碍。 – em70 2010-07-12 18:31:48

0

如何:

let success = 
    try 
     foo() 
     bar() 
     true 
    with :? SomeException -> 
     false 

if success then 
    ... 
else 
    () 
2

我认为最好的惯用代码使用的选项类型:

member t.MyMethod(x : string) : SomeType = 
    let result = 
     try 
      foo() 
      bar() 
      Some(...) 
     with :? SomeException -> 
      None 

    match(result) 
    | Some(...) -> // do other work and return something 
    | None -> // return something 
+0

这就是我在写“我可能将这些语句包装在函数中并使用返回值表示成功/失败的信号”时想到的。对我来说看起来并不真实,也不太有效,但我必须承认它是意识形态。 +1 :) – em70 2010-07-12 18:33:43

0

嗯......你可以做...

type Test() = 
    member this.MyMethod (x:string) = 
     if try 
      foo() 
      bar() 
      true 
      with _ -> false 
     then 
      // do more work 
      "blah" 
     else 
      null 

或者,fl知识产权真/假...

type Test() = 
    member this.MyMethod (x:string) = 
     if try 
      foo(); 
      bar(); 
      false 
      with _ -> true 
     then 
      // bail early 
      null 
     else 
      // do more work 
      "blah" 

强烈推荐从返回null久违的选项类型(有些(X)/无)切换,虽然。让编译器捕获不处理null的地方,而不是你的用户;-)