F# 如何捕获所有异常

F# How to catch all exceptions

我知道如何捕获特定异常,如下例所示:

let test_zip_archive candidate_zip_archive =
  let rc =
      try
        ZipFile.Open(candidate_zip_archive.ToString(), ZipArchiveMode.Read) |> ignore
      zip_file_ok
      with
      | :? System.IO.InvalidDataException -> not_a_zip_file
      | :? System.IO.FileNotFoundException -> file_not_found         
      | :? System.NotSupportedException -> unsupported_exception
  rc

我正在阅读大量文章,看看是否可以在 with 中使用通用异常,例如通配符匹配。这样的构造是否存在,如果存在,它是什么?

是的,你可以这样做:

let foo = 
  try
    //stuff (e.g.)
    //failwith "wat?"
    //raise (System.InvalidCastException())
    0 //return 0 when OK
  with ex ->
    printfn "%A" ex //ex is any exception 
    -1 //return -1 on error

这与 C# 的 catch (Exception ex) { }

相同

要丢弃错误,您可以执行 with _ -> -1(与 C# 的 catch { } 相同)

我喜欢您应用 类型模式 测试的方式(参见 link)。您要查找的模式称为 通配符模式 。您可能已经知道了,但没有意识到您也可以在这里使用它。 要记住的重要一点是 try-catch 块的 with 部分遵循匹配语义。因此,所有其他不错的模式内容也适用于此:

使用您的代码(以及一些修饰以便您可以 运行 它在 FSI 中),这是如何做到的:

#r "System.IO.Compression.FileSystem.dll"
#r "System.IO.Compression.dll"

open System  
open System.IO
open System.IO.Compression

type Status = 
  | Zip_file_ok
  | Not_a_zip_file
  | File_not_found
  | Unsupported_exception
  | I_am_a_catch_all

let test_zip_archive candidate_zip_archive =
  let rc() =
    try
      ZipFile.Open(candidate_zip_archive.ToString(), ZipArchiveMode.Read) |> ignore
      Zip_file_ok
    with
    | :? System.IO.InvalidDataException -> Not_a_zip_file
    | :? System.IO.FileNotFoundException -> File_not_found         
    | :? System.NotSupportedException -> Unsupported_exception
    | _ -> I_am_a_catch_all // otherwise known as "wildcard"
  rc