我使用了一些TCL,但这种结构让我感到困惑。
当$ res =“表不存在”时,以下内容会返回什么?
[list [list {*}$res]]
我知道[list [list $res]]
会做什么,但额外的{*}
只会让我感到困惑。
感谢您的帮助。
答案 0 :(得分:7)
当$ res =“表不存在”时,以下内容会返回什么?
[list [list {*}$res]]
嗯,首先要知道[list {*}…]
是一个构造,它返回省略号中的单词列表(在你的情况下为res
变量的内容)。 发生在你的情况下,净效应是没有的,因为输入字符串实际上也是一个格式良好的列表。然后,它成为外部list
的单个参数,因此我们得到一个单元素列表作为结果,其元素包含单词Table
,does
,{{1}的列表}和not
按顺序排列,即exist
。
扩展单词表单列表对于列表的连接很有用; {Table does not exist}
命令执行类似的操作(但不完全相同; concat
命令中涉及一些历史怪异性)。因此,你可以连接两个这样的列表:
concat
另请注意,扩展(在Tcl 8.5中引入)是 true syntax ,这在Tcl中是非常不寻常的。 set concatenation [list {*}$list1 {*}$list2]
更改了以下替换的性质,以便它产生多个单词而不是一个单词。虽然有可能没有它,但实际上很难做到正确。例如,没有它,上面将是:
{*}
扩展的引入大大减少了大多数Tcl代码所需的set concatenation [eval [linsert $list1 0 list] [lrange $list2 0 end]]
调用次数(这是一个好处,因为它很难正确编写;很多程序员都被困难所困扰)。事实证明,eval
命令在实践中特别有用;这样可以更轻松地使用exec
和glob
:
auto_execok
唉。即使我知道自己在做什么,最后一个有点大脑弯曲,以非扩展形式写出来。 (错误的版本是错误的,因为如果exec {*}[auto_execok $someCmd] $arg1 {*}[glob *.foo]
# Instead of:
#eval [linsert [auto_execok $someCmd] 0 exec] [linsert [glob *.foo] 0 $arg1]
# Or this _wrong_ version:
#eval exec [auto_execok $someCmd] $arg1 [glob *.foo]
包含Tcl元字符,它就会崩溃......)
答案 1 :(得分:5)
它记录在Tcl syntax manual page上。 它在Tcl wiki上进行了讨论。 它被引入TIP 293中的语言(其前身是TIP 157,您可以在其中了解它是如何工作的。)
基本上,{*}$res
会将字符串拆分为以空格分隔的单词。因此,[list {*}$res]
就像[split $res]
一样(在这种情况下)。
最终结果是一个包含一个元素的列表,$ res。
中的单词列表答案 2 :(得分:3)
是的,我总觉得建筑也很麻烦。它被称为扩展,然后巧妙地将它重命名为{*}(非常难忘!)。无论如何,我已经看到它用于扩展列表以使列表内容可用。
请参阅此示例,了解其工作原理:
% set c [list a b]
a b
% set d [list e f]
e f
% set x [list $c {*}$d]
{a b} e f
% set y [lindex $x 2]
f
% set y [lindex $x 1]
e
% set y [lindex $x 0]
a b