Exception 覆盖异常。消息/异常模式匹配
我正在尝试对其定义内的异常进行模式匹配。是否可以使用F的异常语法执行以下操作,或者我必须将exception子类化 这就是我期望的工作:Exception 覆盖异常。消息/异常模式匹配,exception,f#,pattern-matching,Exception,F#,Pattern Matching,我正在尝试对其定义内的异常进行模式匹配。是否可以使用F的异常语法执行以下操作,或者我必须将exception子类化 这就是我期望的工作: exception CoordErr of int * int with override this.Message = let CoordErr(x, y) = this sprintf "(%i %i)" x y //ERROR 但会产生错误: 未定义值或构造函数“x” 未定义值或
exception CoordErr of int * int
with
override this.Message =
let CoordErr(x, y) = this
sprintf "(%i %i)" x y //ERROR
但会产生错误:
未定义值或构造函数“x”
未定义值或构造函数“y”
编辑
我还尝试添加了paren:
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的回答,我想我可以做以下事情来接受未完成匹配警告:
您的第一次尝试不起作用,因为您正在定义一个名为CoordErr的let绑定函数,它会隐藏异常构造函数,这不是您想要的 你的第二次尝试几乎成功了。不幸的是,异常定义的工作方式与区分联合不同:当模式匹配异常构造函数时,要匹配的表达式必须是exn类型,而不是特定的异常子类型。在您的例子中,您正在尝试将这种类型的CoordErr与CoordErr构造函数相匹配。这是如何解决问题的
exception CoordErr of int * int
with
override this.Message =
let (CoordErr(x,y)) = upcast this
sprintf "(%i %i)" x y
您的第一次尝试不起作用,因为您正在定义一个名为CoordErr的let绑定函数,它会隐藏异常构造函数,这不是您想要的 你的第二次尝试几乎成功了。不幸的是,异常定义的工作方式与区分联合不同:当模式匹配异常构造函数时,要匹配的表达式必须是exn类型,而不是特定的异常子类型。在您的例子中,您正在尝试将这种类型的CoordErr与CoordErr构造函数相匹配。这是如何解决问题的
exception CoordErr of int * int
with
override this.Message =
let (CoordErr(x,y)) = upcast this
sprintf "(%i %i)" x y
您可以使用try-with表达式的异常感知模式匹配
exception CoordErr of int * int
with
override this.Message =
try raise this with CoordErr(x, y) -> sprintf "(%i %i)" x y
您可以使用try-with表达式的异常感知模式匹配
exception CoordErr of int * int
with
override this.Message =
try raise this with CoordErr(x, y) -> sprintf "(%i %i)" x y
命名构造函数参数并访问相应字段似乎有效:
exception CoordErr of x : int * y : int
with
override this.Message =
sprintf "(%i %i)" this.x this.y
我意识到这不是一个模式匹配解决方案,但它确实回答了最重要的异常。问题的信息部分: 命名构造函数参数并访问相应字段似乎有效:
exception CoordErr of x : int * y : int
with
override this.Message =
sprintf "(%i %i)" this.x this.y
我意识到这不是一个模式匹配解决方案,但它确实回答了最重要的异常。问题的信息部分: 很好,不完整模式匹配警告是一个小麻烦,但哦,好吧。你能解释一下上抛的必要性吗?没关系。你显然是在我问的时候解释的@kvb-我用避免警告的代码更新了问题。有更好的方法吗?@Daniel-我同意这种行为有点奇怪,而且非常微妙。在某种程度上,它看起来是一致的,尽管:让e=CoordErr1,2导致e具有静态类型exn,而不是CoordErr,所以当将CoordErr用作模式时,也可以使用它来破坏exn值。@Daniel-我会使用nowarn 25,因为您知道在这种情况下模式总是匹配的。不完全模式匹配警告是一个小麻烦,但很好。你能解释一下上抛的必要性吗?没关系。你显然是在我问的时候解释的@kvb-我用避免警告的代码更新了问题。有更好的方法吗?@Daniel-我同意这种行为有点奇怪,而且非常微妙。在某种程度上,它看起来是一致的,尽管:让e=CoordErr1,2导致e具有静态类型exn,而不是CoordErr,所以当将CoordErr用作模式时,也可以使用它来破坏exn值。@Daniel-我会使用nowarn 25,因为你知道在这种情况下模式总是匹配的。我会将它从Unchecked.defaultof更改为failwith impossible我会将它从Unchecked.defaultof更改为failwith impossible这远非理想,因为提升和捕获比常规操作花费的时间要长得多。即使只做一次,这也是一个非常坏的习惯。这远非理想,因为饲养和捕捞要比常规作业花费更多的时间。即使只做一次,这也是一个非常坏的习惯。这可能是最干净的解决方案,但在我提问时命名的联合字段还没有添加到F中。明白了,只是为未来的访问者添加了这个:这可能是最干净的解决方案,但在我提问时命名的联合字段还没有添加到F中。明白了,刚刚为未来的访客添加了以下内容: