问题描述
我有一个功能,需要在以下代码段中使用类型test pattern match (不是try...with
)例外:
module Error =
type Codes =
| InvalidUser = 0
| InvalidEmail = 1
exception AppException of Codes
let errorHandler (e: exn) =
// This doesn't work
match e with
| :? AppException as err(code) ->
code.ToString()
| _ -> e.Message
errorHandler
是一个通用函数,用于捕获应用程序中的AppExeption
以及其他未处理的异常。
如何将模式匹配与类型测试结合使用,并在code
中解构/检索AppException
?
解决方法
要达到最终要完成的目标,我将在此处进行两项更改:
- 将
Codes
从枚举更改为DU - 删除类型测试,因为对于F#定义的异常而言并不必要
它可能看起来像这样:
open System
module Error =
type Codes =
| InvalidUser
| InvalidEmail
exception AppException of Codes
let errorHandler (e: exn) =
match e with
| AppException codes ->
match codes with
| InvalidUser -> "invalid users!"
| InvalidEmail -> "invalid email!"
| _ -> e.Message
或者,如果嵌套模式匹配使您不满意,在这种情况下,您可以将其展平:
let errorHandler (e: exn) =
match e with
| AppException InvalidUser ->
"invalid user!"
| AppException InvalidEmail ->
"invalid email"
| _ -> e.Message
F#定义的例外是有效的区分大小写的联合,可以直接在其上进行模式匹配。这里没有类型测试。
如果Codes
必须保留为枚举,您仍然可以执行第一个代码示例,但是您需要在内部match表达式中使用全包式,因为枚举只是int
下的封面。
let errorHandler (e: exn) =
// This doesn't work
match e with
| AppException codes ->
match codes with
| Codes.InvalidUser -> "invalid users!"
| Codes.InvalidEmail -> "invalid email!"
| _ -> "something else?"
| _ -> e.Message