{*}在TCL中做了什么?

Noa*_*oah 8 list tcl

我使用了一些TCL,但这种结构让我很难受.

当$ res ="表不存在"时,以下将返回什么?

[list [list {*}$res]]
Run Code Online (Sandbox Code Playgroud)

我知道[list [list $res]]会做什么,但额外的东西{*}只会让我困惑.

谢谢你的帮助.

Don*_*ows 7

当$ res ="表不存在"时,以下将返回什么?

[list [list {*}$res]]
Run Code Online (Sandbox Code Playgroud)

好吧,首先要知道这[list {*}…]是一个构造,它返回省略号中的单词列表(res在你的例子中变量的内容).它发生在你的情况下,最终的效果是什么输入字符串其实也是一个结构良好的名单.这便成为一个单一的参数外list,所以我们得到一个单元素列表作为结果,它的元素包含的单词的列表Table,does,notexist按照这个顺序,即{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命令的实践中特别有益; 它与工作globauto_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元字符会崩溃......)


Tro*_*ame 6

是的,我也总是觉得施工很麻烦。它曾经被称为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)


gle*_*man 5

它在Tcl语法手册页上有记录.它在Tcl维基上进行了讨论.它被引入TIP 293中的语言(其前身是TIP 157,您可以在其中了解它的工作原理).

基本上,{*}$res将字符串拆分为以空格分隔的单词.所以,[list {*}$res]行为就像[split $res](在这种情况下).

最终结果是一个包含一个元素的列表,$ res中的单词列表.