我正在尝试在其定义中对异常进行模式匹配。使用F#的异常语法可能会出现以下情况,或者我必须将Exception
子类化为
这是我期望的工作:
exception CoordErr of int * int
with
override this.Message =
let CoordErr(x, y) = this
sprintf "(%i %i)" x y //ERROR
但产生错误:
未定义值或构造函数“x” 值或构造函数“y”未定义
修改
我也尝试过添加parens:
let (CoordErr(x, y)) = this
但这会产生错误:
预计此表达式的类型为exn,但此处的类型为CoordErr
更新
以下作品,但并不理想:
exception CoordErr of int * int
with
override this.Message =
sprintf "(%i %i)" this.Data0 this.Data1
还有其他办法吗?
更新2
从kvb的回答中得到启示,我想我可以执行以下操作来吞下incomplete matches
警告:
exception CoordErr of int * int
with
override this.Message =
match this :> exn with
| CoordErr(x, y) -> sprintf "(%i %i)" x y
| _ -> Unchecked.defaultof<_>
答案 0 :(得分:4)
你的第一次尝试不起作用,因为你正在定义一个名为CoordErr
的let-bound函数,它会影响异常构造函数,这不是你想要的。
你的第二次尝试几乎可行。遗憾的是,异常定义与被区分的联合不同:当与异常构造函数进行模式匹配时,您匹配的表达式必须是exn
类型(而不是特定异常子类型)。在您的情况下,您尝试将this
(类型为CoordErr
)与CoordErr
构造函数进行匹配。这是一个解决方法的原因吗?
exception CoordErr of int * int
with
override this.Message =
let (CoordErr(x,y)) = upcast this
sprintf "(%i %i)" x y
答案 1 :(得分:2)
命名构造函数参数并访问相应的字段似乎有效:
exception CoordErr of x : int * y : int
with
override this.Message =
sprintf "(%i %i)" this.x this.y
我意识到这不是模式匹配解决方案,但它确实回答了问题的“Overriding Exception.Message”部分。 :)
答案 2 :(得分:0)
您可以使用try with expression
的异常识别模式匹配exception CoordErr of int * int
with
override this.Message =
try raise this with CoordErr(x, y) -> sprintf "(%i %i)" x y