Tcl: 如果变量为空,使用默认值的方法是什么?

7
我是一个有用的助手,可以为您翻译文本。

我“继承”了一些Tcl代码,虽然我已经通过一些教程学习了这门语言并且能够理解它,但是我自己编写的Tcl结构缺少某种...技术娴熟。

例如,我有以下代码:

puts "Column 'name': [ $queryRs getString name ]"

$queryRs是SQL查询的结果集。 [ $queryRs getString name ] 结构从结果集中的当前行检索表列“name”的内容。 如果数据库字段为NULL,则puts不会打印任何内容。

我想要打印一个“默认”字符串,即如果[ $queryRs getString name ]没有结果,我想用"--"替换它。

现在,我可以像这样做:

set nameVar "[ $queryRs getString name ]"
if { [ string length $nameVar ] == 0 } {
    set nameVar "--"
}
puts "Column 'name': $nameVar"

但是必须有更紧凑的解决方案,可以在行内完成而不是添加四行和一个临时变量。请帮忙,谢谢?

2个回答

13

两件事。

首先,Tcl 没有空值(NULLnilundefined 或任何其他)的概念和值,当您想要模拟这样的值时,您必须使用一个变量并测试其是否存在或者在arraydictionary条目中使用一个入口并测试其是否存在。如果这样的变量/条目存在,则该值已定义,否则未定义。

不幸的是,您继承的代码的创建者显然没有关注变量可以是NULL的情况,因此NULLs无法与具有默认值(空字符串)的变量区分开来。

接下来,您可以使用一个辅助过程来完成您需要的操作:

proc ValueOrDef {val {def --}} {
   expr {$val ne "" ? $val : $def}
}

然后就像这样:

puts [ValueOrDef [$queryRs getString name]]
puts [ValueOrDef [$queryRs getString name] "some other default"]

啊...我知道默认参数的使用,但没想到可以通过这样的方式传递 name 到函数中。谢谢,这正是我一直在寻找的。 - DevSolar
е—ҜпјҢиҝҷдёӘеҮҪж•°е№¶дёҚжҳҜеҝ…йңҖзҡ„ - дҪ еҸҜд»ҘеғҸ@bmkе»әи®®зҡ„йӮЈж ·д»…дҪҝз”Ёexprе’Ңе®ғзҡ„дёүе…ғжқЎд»¶иҝҗз®—з¬Ұ; дёҖдёӘдё“й—Ёзҡ„еҮҪж•°еҸӘжҳҜи®©ж„Ҹеӣҫжӣҙжё…жҷ°гҖӮ - kostix
1
是的,但通常最好让定义复杂而使用简单,而不是相反。 - DevSolar
嗯... Tcl 实际上有类似于 "ne" 的东西吗?我不得不用 [string length $val] > 0 替换 $val ne "" 才能让你的代码运行... - DevSolar
@DevSolar,当然可以(http://www.tcl.tk/man/tcl8.5/TclCmd/expr.htm#M14),只是你的Tcl版本早于8.4,这意味着它比尘土还要古老--请参阅时间轴(http://wiki.tcl.tk/1721)。请注意,8.4已经停止维护,而8.6即将发布。如果可能,请考虑升级到8.5。 - kostix
严格来说,8.4版本只会有一个补丁发布,该补丁将在8.6.0发布后发布。它将修复一些错误,这些错误恰好很容易进行修复(我需要检查存储库以了解确切情况)。 - Donal Fellows

4
你可以使用expr命令的x?y:z结构。其中,x是条件,如果条件达成,则返回y,如果条件未能达成,则返回z。 例如(但仍需使用临时变量):
set nameVar [ $queryRs getString name ]
puts "Column 'name': [expr {[string length $nameVar]>0 ? $nameVar : "--"}]"

一行代码总是更受欢迎 +1 - tetris11

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,