2010-07-12 92 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的地方,而不是你的用戶;-)