gpt4 book ai didi

tcl - 为什么 "dict get"命令中没有内置异常处理?

转载 作者:行者123 更新时间:2023-12-02 08:27:54 26 4
gpt4 key购买 nike

当字典首次实现并添加到 Tcl 中时,为什么 dict get 命令的实现方式允许在尝试检索字典中不存在的键的值时发生错误?

如果要确保完全安全,则需要在每次使用命令时将命令包装在 catch 语句中。在我看来,像这样经常使用的命令总是会内置某种异常处理。

最佳答案

这是 Tcl(以及其他一些语言)中的常见设计选择。当像 dict get(或者更常见的是 open)这样的命令失败时,程序必须处理它,这意味着它必须在某些方面被警告失败方式。

最常见的选项是让失败的命令要么

  1. 返回域外值(例如在具有它的语言中为 null),或者

  2. 引发异常。

(例如,lsearch 命令在成功时返回索引值,在失败时返回 -1(第一个选项)。dict get 命令在以下情况下返回值成功并在失败时引发异常(第二个选项)。)

第一个选项对于 dict get 命令来说并不实际,因为没有域外值。任何 Tcl 值都可能存储在字典中,因此您无法查看 dict get 的结果并知道它找不到值。空字符串在 Tcl 中经常用作伪空值,但很可能空字符串是字典中的实际值。

因此 dict get 在失败时引发异常。也不是那么坏。异常有很多简洁的属性,例如直接将控制权交给最近的封闭处理程序,而不管它必须展开多少堆栈级别。

(处理命令中的所有异常是不可能的:处理程序必须知道如何处理错误,而 dict get 无法知道。)

无论哪种方式,可能会失败的命令都需要包含在某种检查中。如果 foo 命令用于获取可能不可用的资源并且没有合理的默认值,则调用它的代码必须如下所示:

if {[set x [foo]] ne {BAD_RETURN_VALUE}} {
# use the resource
} else {
# deal with failure
}

或者像这样:

try {
foo
} on ok x {
# use the resource
} on error {} {
# deal with failure
}

或者像这样(如果预测 foo 是否成功的谓词函数存在):

if {[foo-will-succeed]} {
set x [foo]
# use the resource
} else {
# deal with failure
}

这在每种情况下都差不多。由于域外值在 Tcl 中很少见并且错误处理非常通用,因此通常倾向于使用谓词或异常策略。

patthoyts 已经展示了一种向 dict 集合添加错误抑制 getter 函数的方法。另一个相对轻量级的调用是

set foo [try {dict get $bar xyzzy} on error {} {}]

如果成功则返回 dict get 调用的结果,如果失败则返回空字符串,并压缩任何引发的错误。

set foo [try {dict get $bar xyzzy} on error {} {return 42}]

此调用设置了一个默认返回值以在失败时使用。

如果调用还是很麻烦,可以做成命令:

proc dictget args {
set default {}
if {[lindex $args 0] eq {-default}} {
set args [lassign $args - default]
}
try {
dict get {*}$args
} on error {} {
set default
}
}

大纲是

dictget ?-default ? ?字典值? ? ...?

文档:dict , if , proc , return , set , try

关于tcl - 为什么 "dict get"命令中没有内置异常处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30309194/

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