我对反斜杠运算符感到困惑,因为它在以下示例中使用:
foreach op {+ - * / %} {proc $op {a b} "expr {\$a $op \$b}"}
Run Code Online (Sandbox Code Playgroud)
当反斜杠在花括号内时,将执行键盘输入(以前缀表示法).当我删除反斜杠时,错误消息是"无法读取"":没有这样的变量".
谷歌搜索这个只是一遍又一遍地告诉我关于逃脱角色和线路延续.这个上下文中的反斜杠操作符是不同的:\ $ a接受键盘输入怎么样?我应该搜索"TCL反斜杠操作符"以外的其他内容吗?
您的观察(或您用来描述它的语言)是不正确的.反斜杠不接受键盘输入.它仅用作转义字符,仅此而已.在这种情况下,它的行为并没有什么特别之处.
让我们从查看代码试图完成的内容开始.它试图创建这样的过程:
proc + {a b} {
expr {$a + $b}
}
proc - {a b} {
expr {$a - $b}
}
Run Code Online (Sandbox Code Playgroud)
... 等等.只是,它是在一个循环中进行的,其中运算符和proc名称在变量中.
如果您将原始代码拆分为几行,则可能更容易想象正在发生的事情:
foreach op {+ - * / %} {
proc $op {a b} "expr {\$a $op \$b}"
}
Run Code Online (Sandbox Code Playgroud)
请注意,循环内部是一个几乎正常的proc定义.但是,不是使用花括号来定义proc(proc $op {a b} {...})的主体,而是使用双引号(proc $op {a b} "...").因为它使用双引号,所以在foreach命令运行时会评估proc主体中的所有内容.这就是为什么你得到关于没有名为"a"的变量的错误."a"未在foreach循环中定义,也不是"b".仅定义了"op".
为防止$a在foreach命令运行时被替换,反斜杠用于逃避特殊含义$.因此,"expr {\$a $op \$b}"变成expr {$a + $b}(或-,或*等).
为什么这样做?想象一下,如果proc语句使用了更传统的花括号:
foreach op {+ - * / %} {
proc $op {a b} {
expr {$a $op $b}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,$a并且$b只是正常过程中的正常变量.到现在为止还挺好.但是,有一个问题.注意$op?proc不知道是什么$op,所以如果你实际运行上面的代码然后尝试使用其中一个创建的新proc ,你会得到一个名为的未知变量的错误op.
所以,有一个矛盾:你想$a和$b从字面上$a和$b,但你想$op用的值来代替$op从环路.对?因此,在这种情况下,编写代码的人决定使用双引号而不是花括号来定义proc - 完全合法,尽管有点不常见.这意味着proc的主体中的每个变量都将在foreach运行时进行评估.这是伟大的$op,但不是伟大的$a和$b.因此,为了在foreach运行时保持这些变量不扩展,美元符号将被转义.
因此,当foreach运行时,它会创建一个具有看起来像expr {$a + $b},expr {$a - $b}等等的主体的过程.