Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Exception 覆盖异常。消息/异常模式匹配_Exception_F#_Pattern Matching - Fatal编程技术网

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” 未定义值或

我正在尝试对其定义内的异常进行模式匹配。是否可以使用F的异常语法执行以下操作,或者我必须将exception子类化

这就是我期望的工作:

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中。明白了,刚刚为未来的访客添加了以下内容: