我在一个变量中有一个数字,比如10,在另一个变量中有一个字符串,比如+1或-2。在上述情况下,我需要评估10+1或10-2。
所以,我有
set foo 10
set garp -1如果我做了
expr $foo $garp一切都很好(我得到9)。
阿!但是通常,您应该将大括号放在expr表达式的周围。
expr {$foo $garp}missing operator at _@_ in expression $foo _@_$garp失败。
类似地,
expr [concat $foo $garp]效果很好,但是
expr {[concat $foo $garp]}返回10 -1。
我不想让这个表达式没有真正的理解,因为我担心,否则我,或者其他人,会把大括号放在表达式上,代码就会停止工作。
做这件事的“正确”方法是什么?
发布于 2016-07-09 23:46:21
一般来说,expr涉及两轮替换。
第一轮替换由命令解析器对不包含在大括号中的expr命令的参数执行。生成的字符串被连接(通过在它们之间添加分隔符空间)到单个表达式字符串中,然后由表达式处理器解析(然后计算)。
在解析过程中,表达式被分解为运算符和操作数。操作数必须用运算符分隔。假设关注数学表达式(即丢弃字符串操作),操作数可以是下列之一:
$表示法的Tcl变量。变量的值将用作操作数.项2和3对应于由表达式处理器在评估期间执行的第二轮替换。在这一步中执行的每一个替换都将产生一个可以直接用于进一步计算的数值,而不需要重新解析和重新评估它。
说了这些之后,让我们看看您的例子:
expr $foo $garp在第一轮替换到expr 10 -1期间,命令处理器将其展开,参数连接后的表达式字符串为{10 -1},表达式处理器将其解析为有效的表达式10 subtract 1。
expr [concat $foo $garp]在第一轮替换过程中,命令处理器将其扩展到expr {10 -1},有效地产生与前一种情况相同的表达式字符串。
expr {$foo $garp}命令处理器保持原样,表达式处理器看到两个连续的操作数(对应于上面的第2条),它们之间没有任何操作符。
expr {[concat $foo $garp]}同样,第一轮替代没有执行。解析该表达式将提取与第3条对应的单个操作数[concat $foo $garp]。表达式处理器计算命令,并将其结果(即字符串"10 -1")替换为完整表达式的结果。
因此,表达式的正确大括号版本必须读到:
expr {$foo + $garp}它将被解析为$foo add $garp。
https://stackoverflow.com/questions/38286619
复制相似问题