Tcl [list abc] vs {abc}是否有区别,在什么情况下?

Der*_*itz 3 tcl

我正在玩Tcl并找到了几个[list a b c]可以互换的场景{a b c}.什么是首选方法,哪里不[list a b c]符合行为{a b c}

bta*_*bta 7

% set lista [list a b c]
a b c
% set listb {a b c}
a b c
% set b {1 2 3}
1 2 3
% set lista [list a $b c]
a {1 2 3} c
% set listb {a $b c}
a $b c
Run Code Online (Sandbox Code Playgroud)

使用文字构建列表时,这两种形式是等效的.当您使用变量时,[list ...]表单将扩展变量,然后将其放入字符串中,而{...}表单则不会.

基本上,{...}将其中的任何内容视为单个连续的字符串; 特殊字符$永远不会被解释.该[list ...]语句采用其参数并将它们连接在一起,用空格分隔.因此,如果您正在使用的项目是字符串文字并且不包含任何需要解释的内容,那么这两个表单是相同的.


Don*_*ows 5

对于文字,它们在所有功能方面都是相同的(除此之外,直接文字形式当然稍快).对于非文字,他们显然做了不同的事情(如bta所说).

但是,还有更多的东西.让我们深入了解!

在某些情况下,您希望使用表单{…}"…"表单,而这正是在使用某些非文字时.特别是,如果您使用的是tcomTcl/Java(即Jacl或TclBlend),那么您将使用不能正确遵守Tcl语义的对象.特别是,你会将"脆弱"的对象附加到某些值上; 如果Tcl_Obj包含对值的引用的类型已更改(在Tcl用语中为"shimmered"),那么对底层COM或Java对象的引用将无法挽回地丢弃,垃圾收集器将在您完成之前删除该对象.使用[list …]表单构建列表(和列表操作,如lindex 检索)将确保正确维护这些脆弱的内部表示,直到您不再需要它们为止.

对于正常的Tcl值,包括大多数扩展包产生的值,除了要注意使用非有损操作也更快之外,您不必担心这一点.如果你想让你的代码快速(谁没有?),那么[list]即使没有必要(通常​​是这样),你的朋友也是如此.

您要注意的另一种情况是在生成回调时.

通常,您希望进行回调,其中某些值在创建回调时已知,而不是存储在执行回调时存在的某个变量中.(我这个做很多事after,fileeventtrace,但也有很多的地方,这样做)是与创建回调脚本list(或其他一些名单产生指令)是不是因为Tcl脚本的评估引擎的所有其他办法更快可以证明他们没有替换并直接将列表元素提供给命令调度程序.当您将值传递给过程时,这是一个非常有利的优势,这被认为是回调的良好实践.