2

这听起来可能很愚蠢。忍受我。在玩弄时expr,我遇到了以下场景

proc badExpr { a b } { 
    return expr $a+$b
}

proc goodExpr { a b } { 
    return [ expr {$a+$b} ]
}

puts "Bad Expression Result : --->[ badExpr 1 3 ]<-----"
puts "Good Expression Result : [ goodExpr 1 3 ]"

输出:

Bad Expression Result : ---><-----
Good Expression Result : 4

如您所见,procbadExpr正在返回一个空字符串。只是出于好奇,我很想知道它为什么返回一个空字符串?

4

3 回答 3

2

(1) proc badExpr { ab } { return expr $a+$b }

在您上面的 badExpr 中,您没有使用 TCL expr 命令。上面的 expr 被视为与任何其他字符串一样。如果您确实想使用该命令expr,则必须将其放在方括号中。所以应该是return [expr $a + $b]

return 命令返回一个字符串值,您还可以指定各种选项。根据以下来自http://www.tcl.tk/man/tcl/TclCmd/return.htm的文档,最后一个值是实际的返回结果。

return ?result?
return ?-code code? ?result?
return ?option value ...? ?result?

但是,如果您有偶数个任意参数,则它不会返回任何内容。我不确定幕后发生了什么,但是当您使用 -code 或 option 时,您将有一个与之关联的值参数。因此,它似乎可能将每一对视为选项/值或代码/值,并返回最后一个未关联的项目作为结果。

#Returns 3
return 1 2 3 4 3

#Returns nothing
return 1 2 3

(2) expr {$a+$b} 起作用的原因是因为它是proc中的最后一个表达式。如果一个过程不执行显式返回,那么它的返回值是在过程主体中执行的最后一个命令的值。它不需要是 expr {$a+$b},它可以是 expr $a+$b,就像你的 badExpr 一样。

于 2014-10-26T04:09:20.743 回答
1

简而言之,问题在于您的调用周围没有括号expr

return expr $a+$b   ;# no worky
return [expr $a+$b] ;# works (but you should have braces around the arguments)

它没有明确记录,但似乎可以return接受任意数量的参数。如果参数列表是偶数大小,则该命令返回空字符串。如果参数的数量是奇数,则返回最后一个参数。这与文档一致:正常的参数列表由一个可选的结果值组成,前面有零个或多个选项名称/值对。这仍然有点出乎意料,因为人们会认为选项名称被限制为有用的名称。

哦!如果return是脚本中的最后一个命令,并且它的唯一参数是脚本评估(括号内的代码),您总是可以跳过return(字节编译器无论如何都会消除它)。

proc goodExpr { a b } { 
    return [ expr {$a+$b} ]
}

是相同的

proc goodExpr { a b } { 
    expr {$a+$b}
}

文档:exprreturn

于 2014-10-25T09:31:23.580 回答
1

有趣的是,abadExpr会是这样的:

proc badExpr { a b } { 
    return [expr $a+$b]
}

实际上得到的是weirdExpr

proc badExpr { a b } { 
    return expr $a+$b
}

这真的有什么作用?它在结果字典中设置内容。Tcl 结果实际上应该被认为是三件事的三元组:结果代码(一个小整数,在这种情况下0为 OK —1将用于抛出错误,并且您通常可以忽略其他几个错误)一个结果值(您通常返回的内容)和结果字典。结果字典主要用于错误,保存诸如堆栈跟踪(用于填充errorInfo全局变量)、发生错误的行号、计算机可读的错误描述(用于填充errorCode全局变量)等,但它可以容纳任何旧的东西。而且您在其中添加了一些非常奇怪的东西(因为这就是return工作原理);系统定义的键都以-使它们看起来像普通选项(字典本身通常称为选项字典)。

让我们使用双变量形式来展示这一点catch(第二个变量捕获字典):

% proc weirdExpr { a b } { 
    return expr $a+$b
}
% catch {weirdExpr 1 3} p q
0
% puts $p
% puts $q
expr 1+3 -code 0 -level 0

是的,里面有一个有趣的条目,expr它的值是1+3……</p>

于 2014-10-26T13:11:01.563 回答