错误

运行时错误

在运行代码时, 会发生一些非拼写的错误, 例如:

除零错误

1 / 0
// 输出: division by zero

数组越界

arr = [1]
arr[8] // 尝试读取索引为8的元素, 但实际上长度仅为1
// 输出: reflect: slice index out of range

Go原生错误

在调用Go标准库、第三方库时, 会有很多方法返回值为[结果…, 错误信息], 例如

// Go标准库 - 字符串转整型方法
strconv.Atoi("NaN")

在Go中, 以上方法的签名是

package strconv
...
func Atoi(s string) (int, error) {
    ...
}

返回值包含int和error类型, 此时Z1h返回的结果是一个数组:

res = strconv.Atoi("NaN")
// 输出: [ 0, { "Func": "Atoi", "Num": "NaN", "Err": {} } ]

此时可以通过对第[1]个参数是否为空来校验是否抛出了错误, 如果为空, 则[0]是需要的结果

res = strconv.Atoi("NaN")
if (res[1]) {
    print('产生了错误:', res[1].Error())
} else {
    print('得到了答案:', res[0])
}

可以将上例的"NaN"替换成"123"试试

抛出错误

当代码运行到某处, 需要强行中断后续操作并将错误信息往上传递时, 需要抛出异常

  • 调用panic函数即可抛出错误
  • 调用assert方法时, 传入的参数内如果包含错误, 也会抛出其中的错误

示例

panic的用法

panic("Bye")
print("这里不会被执行")
// 输出: Panic at call func: Bye

assert的用法

print(assert(strconv.Atoi("123")))
print(assert(strconv.Atoi("NaN")))
print("这里不会被执行")
// 第一行会输出123
// 第二行会抛出错误
// 第三行会被第二段打断, 不会被执行

错误处理

try catch代码块

Z1h语言中, 可以使用try {...} catch(e) {...}代码块来统一捕获抛出的异常

如下文, 捕获了字符串转整型的异常并处理

var str = "不是数字"; // 可以替换成"888"试试
try {
    var num = assert(strconv.Atoi(str));
    print("得到了数字:", num);
} catch (e) {
    print(`字符串 ${str} 不是一个合法的整型: ${e.Error()}`);
}

?? + recover 捕获

可参考 运算符 > ?? 操作符 > recover 学习如何使用 ??recover 进行错误的捕获和处理

示例:

panic(123) ?? recover(err=>`抛出的内容是: ${err.Origin()}`)