{*} 在 TCL 中做什么?

发布于 2024-10-19 07:24:58 字数 204 浏览 3 评论 0原文

我用过一些TCL,但这个结构难倒了我。

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

[list [list {*}$res]]

我知道 [list [list $res]] 会做什么,但额外的 {*} 只是让我感到困惑。

谢谢你的帮助。

I have used some TCL, but this construction stumps me.

When $res = "Table does not exist", what will the following return?

[list [list {*}$res]]

I know what [list [list $res]] would do, but the extra {*} just baffles me.

Thanks for helping.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

这样的小城市 2024-10-26 07:24:58

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

[列表 [列表 {*}$res]]

好吧,首先知道 [list {*}...] 是一个返回省略号中单词列表的构造(在您的情况下是 res 变量的内容) 。在您的情况下,碰巧没有任何净效果,因为输入字符串实际上也是一个格式良好的列表。然后,它成为外部 list 的单个参数,因此我们得到一个单元素列表作为结果,其元素包含单词 Table 的列表,确实存在按此顺序,即{表不存在}

扩展注意事项

扩展单词形式的列表对于进行列表的串联很有用; concat 命令执行类似的操作(但不相同;concat 命令涉及一些历史上的怪异现象)。因此,您可以像这样连接两个列表:

set concatenation [list {*}$list1 {*}$list2]

另请注意,扩展(在 Tcl 8.5 中引入)是真正的语法,这在 Tcl 中是非常不寻常的事情。 {*} 改变了以下替换的性质,使其产生多个单词而不是一个。虽然没有它也是可以的,但实际上很难做到正确。例如,如果没有它,上面的内容将是:

set concatenation [eval [linsert $list1 0 list] [lrange $list2 0 end]]

扩展的引入大大减少了大多数 Tcl 代码中所需的 eval 调用次数(这是一个好处,因为很难正确编写;很多程序员被困难所困扰)。事实证明,这在使用 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]

呃。尽管我知道自己在做什么,但以非扩展形式写出最后一个有点费脑筋。 (错误的版本是错误的,因为如果 $arg1 包含 Tcl 元字符,它就会崩溃......)

When $res = "Table does not exist", what will the following return?

[list [list {*}$res]]

Well, first know that [list {*}…] is a construct that returns a list of the words in the ellipsis (the contents of the res variable in your case). It happens that in your case, the net effect is nothing as the input string is actually also a well-formed list. That then becomes a single argument to the outer list and so we get a single-element list as result, whose element contains a list of the words Table, does, not and exist in that order, i.e., {Table does not exist}.

Notes on expansion

The list of expanded word form is useful for doing concatenation of lists; the concat command does something similar (but not identical; there are some historical weirdnesses involved in the concat command). Thus, you'd concatenate two lists like this:

set concatenation [list {*}$list1 {*}$list2]

Also note that expansion (introduced in Tcl 8.5) is true syntax, which is a very unusual thing in Tcl. The {*} changes the nature of the following substitution so that it yields multiple words instead of just one. While it is possible to do without it, it's actually remarkably difficult to get right. For example, without it the above would be:

set concatenation [eval [linsert $list1 0 list] [lrange $list2 0 end]]

The introduction of expansion has greatly reduced the number of calls to eval required in most Tcl code (a benefit since it was hard to write properly; a lot of programmers were caught out by the difficulty). This has proved particularly beneficial in practice with the exec command; it makes working with glob and auto_execok much easier:

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]

Ugh. That last one was a bit brain-bending to write out in non-expansion form even though I know what I'm doing. (The wrong version is wrong because it falls apart if $arg1 contains Tcl meta-characters…)

瞳孔里扚悲伤 2024-10-26 07:24:58

它记录在 Tcl 语法手册页上。
Tcl wiki 对此进行了讨论。
它在 TIP 293 中被引入到语言中(其前身是 TIP 157,您可以在其中了解其工作原理)。

本质上,{*}$res 会将字符串分割成以空格分隔的单词。因此,[list {*}$res] 的作用就像[split $res](在本例中)。

最终结果是一个只有一个元素的列表,即 $res 中的单词列表。

It's documented on the Tcl syntax manual page.
It's dicussed on the Tcl wiki.
It was introduced into the language in TIP 293 (its predecessor was TIP 157 where you can learn how it works).

Essentially, {*}$res will split the string into its whitespace-separated words. So, [list {*}$res] acts just like [split $res] (in this case).

The end result is a list with one element, the list of the words in $res.

自在安然 2024-10-26 07:24:58

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

Yeah I always find that construction troublesome too. It used be called expand and then they cleverly renamed it to {*} (very memorable!). Anyway I've seen it used to expand a list to make the list contents available.

See this example for an idea of how it works:

% 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文