前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >错误处理

错误处理

作者头像
冬夜先生
发布2022-01-05 09:58:08
6490
发布2022-01-05 09:58:08
举报
文章被收录于专栏:csico

计算 M 表达式的结果会产生以下结果之一:

  • 产生单个值。
  • 出现错误,表明对表达式求值的过程无法产生值。错误包含单个记录值,可用于提供有关导致评估不完整的原因的附加信息。

错误可以从表达式中引发,也可以从表达式中处理。

引发错误

引发错误的语法如下:

错误引发表达式: error 表达式

文本值可用作错误值的简写。例如:

复制

代码语言:javascript
复制
error "Hello, world" // error with message "Hello, world"

完整的错误值是记录,可以使用以下Error.Record函数构造:

复制

代码语言:javascript
复制
error Error.Record("FileNotFound", "File my.txt not found",
     "my.txt")

上面的表达式等价于:

复制

代码语言:javascript
复制
error [ 
    Reason = "FileNotFound", 
    Message = "File my.txt not found", 
    Detail = "my.txt" 
]

引发错误将导致当前表达式计算停止,并且表达式计算堆栈将展开,直到发生以下任一情况:

  • 到达记录字段、部分成员或 let 变量——统称为一个条目。该条目被标记为有错误,错误值与该条目一起保存,然后传播。对该条目的任何后续访问都将导致引发相同的错误。记录、节或 let 表达式的其他条目不一定会受到影响(除非它们访问先前标记为有错误的条目)。
  • 达到了顶级表达式。在这种情况下,评估顶级表达式的结果是错误而不是值。
  • try达到了一个表达式。在这种情况下,错误被捕获并作为值返回。

处理错误

一个错误处理表达式是用来处理一个错误:

_error-handling-expression: try protected-expression other-clause opt protected-expression:       expression other-clause: otherwise default-expression default-expression:       expression

的评价时以下成立错误处理表达没有otherwiseclause

  • 如果protected-expression 的求值没有导致错误并产生值x,则error-handling-expression 产生的值是以下形式的记录:

复制

代码语言:javascript
复制
    [ HasErrors = false, Value = x ]
  • 如果受保护表达式的求值产生错误值 e,则错误处理表达式的结果是以下形式的记录:

复制

代码语言:javascript
复制
    [ HasErrors = true, Error = e ]

的评价时以下成立错误处理表达otherwiseclause

  • 必须在其他子句之前评估受保护的表达式。
  • 当且仅当对受保护表达式的求值引发错误时,必须对其他子句求值。
  • 如果protected-expression的求值引发错误,则error-handling-expression产生的值是对others-clause 求值的结果。
  • 传播在其他条款评估期间引发的错误。

以下示例说明了未引发错误的情况下的错误处理表达式

复制

代码语言:javascript
复制
let
    x = try "A"
in
    if x[HasError] then x[Error] else x[Value] 
// "A"

以下示例显示引发错误然后处理它:

复制

代码语言:javascript
复制
let
    x = try error "A" 
in
    if x[HasError] then x[Error] else x[Value] 
// [ Reason = "Expression.Error", Message = "A", Detail = null ]

可以使用 else 子句将 try 表达式处理的错误替换为替代值:

复制

代码语言:javascript
复制
try error "A" otherwise 1 
// 1

如果 else 子句也引发错误,那么整个 try 表达式也会引发错误:

复制

代码语言:javascript
复制
try error "A" otherwise error "B" 
// error with message "B"

记录错误和 let 初始值设定项

以下示例显示了一个记录初始值设定项,其字段A引发错误并由其他两个字段B和访问C。FieldB不处理由 引发的错误A,但C会处理。final 字段D不会访问A,因此它不受A.

复制

代码语言:javascript
复制
[ 
    A = error "A", 
    B = A + 1,
    C = let x =
            try A in
                if not x[HasError] then x[Value]
                else x[Error], 
    D = 1 + 1 
]

对上述表达式求值的结果是:

复制

代码语言:javascript
复制
[ 
    A = // error with message "A" 
    B = // error with message "A" 
    C = "A", 
    D = 2 
]

M 中的错误处理应该在接近错误原因的地方执行,以处理延迟字段初始化和延迟闭包评估的影响。以下示例显示了使用try表达式处理错误的失败尝试:

复制

代码语言:javascript
复制
let
    f = (x) => [ a = error "bad", b = x ],
    g = try f(42) otherwise 123
in 
    g[a]  // error "bad"

在此示例中,定义g旨在处理调用f. 但是,该错误是由字段初始值设定项引发的,该初始值设定项仅在需要时运行,因此在从 f 返回记录并通过try表达式之后。

未实现错误

在开发表达式时,作者可能希望省略表达式某些部分的实现,但仍希望能够执行表达式。处理这种情况的一种方法是为未实现的部分引发错误。例如:

复制

代码语言:javascript
复制
(x, y) =>
     if x > y then
         x - y
     else
         error Error.Record("Expression.Error", 
            "Not Implemented")

省略号 ( ...) 可用作 的快捷方式error

未实现的表达式: ...

例如,以下等效于前面的示例:

复制

代码语言:javascript
复制
(x, y) => if x > y then x - y else ...

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引发错误
  • 处理错误
  • 记录错误和 let 初始值设定项
  • 未实现错误
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档