2

使用 Tcl switch 命令时必须有一个额外的评估级别。这是 repl 上的一个示例会话,以说明我的意思:

$ tclsh
% regexp {^\s*foo} " foo"
1
% regexp {^\\s*foo} " foo"
0
% switch -regexp " foo" {^\\s*foo {puts "match"}}
match
% switch -regexp " foo" {{^\s*foo} {puts "match"}}
match

...需要在第一个“切换”版本中添加一个额外的反斜杠。这在 Windows 上的 8.5.0 和 8.6.0 之间是一致的。有人可以指出手册中描述这种和类似的额外取消引用级别实例的部分吗?我的第一个想法是第一个“switch”版本中的大括号会保护反斜杠,但“switch”本身必须对模式应用额外的反斜杠替代。除非我误解了其他事物的细微差别。

编辑: ...嗯...就像约翰内斯·库恩(Johannes Kuhn)所说,下面的反斜杠替换显然取决于使用的动态上下文,而不是创建的词汇上下文...

% set t {\s*foo}
\s*foo
% proc test_s x {set x}
% test_s $t
\s*foo
% proc test_l x {lindex $x 0}
% test_l $t
s*foo
% puts $t
^\s*foo

...这似乎是一个非常有趣的设计选择。

4

1 回答 1

2

您在此处描述的问题很容易解决:

switch和之间的区别在于regexpswitch 实际上需要一个列表。
所以如果我们打印列表的第一个{^\s*foo {puts "match"}}元素

% puts [lindex {^\s*foo {puts "match"}} 0]
^s*foo

它会导致我们不想要的东西。

列表构造有点复杂,如果您不确定,请使用交互式 Tcl shell 为您构造一个list

编辑:确实,这是一个有趣的设计选择,但这适用于 Tcl 中的所有内容。例如expr,使用为算术表达式设计的小型语言。它应该如何处理它的参数取决于命令。甚至像if, for,之类的语言while结构也只是将其中一个参数视为表达式,将其他参数视为脚本的命令。这种设计使得创建新的控制结构成为可能,例如 sqlite 的 eval,它采用 SQL 语句和一个脚本,它应该为每个结果评估。

于 2013-09-11T18:38:28.013 回答