我使用了一些TCL,但这种结构让我很难受.
当$ res ="表不存在"时,以下将返回什么?
[list [list {*}$res]]
Run Code Online (Sandbox Code Playgroud)
我知道[list [list $res]]
会做什么,但额外的东西{*}
只会让我困惑.
谢谢你的帮助.
当$ res ="表不存在"时,以下将返回什么?
Run Code Online (Sandbox Code Playgroud)[list [list {*}$res]]
好吧,首先要知道这[list {*}…]
是一个构造,它返回省略号中的单词列表(res
在你的例子中变量的内容).它发生在你的情况下,最终的效果是什么输入字符串其实也是一个结构良好的名单.这便成为一个单一的参数外list
,所以我们得到一个单元素列表作为结果,它的元素包含的单词的列表Table
,does
,not
并exist
按照这个顺序,即{Table does not exist}
.
扩展单词表单列表对于列表的连接很有用; 该concat
命令执行类似的操作(但不完全相同; concat
命令中涉及一些历史怪异).因此,您将连接两个列表,如下所示:
set concatenation [list {*}$list1 {*}$list2]
Run Code Online (Sandbox Code Playgroud)
另请注意,扩展(在Tcl 8.5中引入)是真正的语法,这在Tcl中是非常不寻常的.该{*}
变化以下的替换,使其产生多个单词而不是一个性质.虽然有可能没有它,但实际上很难做到正确.例如,没有它,上面将是:
set concatenation [eval [linsert $list1 0 list] [lrange $list2 0 end]]
Run Code Online (Sandbox Code Playgroud)
扩展的引入大大减少了eval
大多数Tcl代码所需的调用次数(这是一个好处,因为它很难正确编写;很多程序员都被困难所困扰).事实证明,这在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]
Run Code Online (Sandbox Code Playgroud)
啊.即使我知道自己在做什么,最后一个有点大脑弯曲,以非扩展形式写出来.(错误的版本是错误的,因为如果$arg1
包含Tcl元字符会崩溃......)
是的,我也总是觉得施工很麻烦。它曾经被称为expand,然后他们巧妙地将其重命名为{*}(非常难忘!)。无论如何,我已经看到它用于扩展列表以使列表内容可用。
请参阅此示例以了解其工作原理:
% 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
Run Code Online (Sandbox Code Playgroud)
它在Tcl语法手册页上有记录.它在Tcl维基上进行了讨论.它被引入TIP 293中的语言(其前身是TIP 157,您可以在其中了解它的工作原理).
基本上,{*}$res
将字符串拆分为以空格分隔的单词.所以,[list {*}$res]
行为就像[split $res]
(在这种情况下).
最终结果是一个包含一个元素的列表,$ res中的单词列表.