gpt4 book ai didi

f# - 为什么在这种情况下模式匹配会因异常而失败?

转载 作者:行者123 更新时间:2023-12-05 01:20:57 24 4
gpt4 key购买 nike

我有这个简单的异常层次结构:

type FirstLevelException(msg) = inherit System.Exception (msg)
type SecondLevelException(msg, inner) = inherit System.Exception (msg, inner)
type ThirdLevelException(msg, inner) = inherit System.Exception (msg, inner)

还有这三个(虚拟)函数:

member this.FirstFunction a =
raise (new FirstLevelException("one"))

member this.SecondFunction a =
try
this.FirstFunction a
with
| :? FirstLevelException as ex -> raise (new SecondLevelException("two", ex))

member this.ThirdFunction a =
try
this.SecondFunction 25
with
| :? SecondLevelException as ex -> raise (new ThirdLevelException("three", ex))

在调用 ThirdFunction 时很容易看出:

  • firstFunction 引发 FirstLevelException
  • secondFunction 捕获它,将其包装到 SecondLevelException 中并抛出它
  • thirdFunction 捕获它,将其包装到 ThirdLevelException 中并抛出它
  • 调用者可以捕捉到 ThirdLevelException。

一切都好。现在我通过以下方式更改thirdFunction:

member this.ThirdFunction a =
25 |>
try
this.SecondFunction
with
| :? SecondLevelException as ex -> raise (new ThirdLevelException("three", ex))

事情变得很奇怪:看起来 ThirdFunction 中的模式匹配不再起作用,并且 SecondLevelException 一直传播到 ThirdFunction 调用者,而没有被包装在 ThirdLevelException 中。

我确信有一个逻辑解释,我的 C# 变形的头脑看不到。有人可以解释一下吗?

最佳答案

你描述的行为是正确的——当你写 25 |> expr , expr 中的代码求值,然后用 25 调用结果(一个函数)作为论据。

在您的情况下,expr 的结果是一个函数,表达式的计算(返回函数)受你的 try 保护。堵塞。但是,一旦函数返回,它会转义 try block 并且调用是在异常处理程序之外进行的。

要将异常处理移到这个返回的函数中,你必须这样写:

25 |> (fun n ->
try
// You need to call the function (i.e. give it something as an argument)
// inside the try-with block, otherwise it won't be executed here!
this.SecondFunction n
with
| :? SecondLevelException as ex -> raise (new ThirdLevelException("three", ex)))

在实践中没有人会写这种代码,但我希望它能说明问题!

顺便说一句:我想这与您之前关于在管道中处理异常的 SO 问题有关。我 added answer there ,这可以帮助您理解问题。 (问题是在 try .. with 中包装管道操作不会阻止在管道函数内部发生异常。

关于f# - 为什么在这种情况下模式匹配会因异常而失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8263115/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com