代码之家  ›  专栏  ›  技术社区  ›  Derek Litz

Tcl[list a b c]与{a b c}有区别吗?在什么上下文中?

tcl
  •  3
  • Derek Litz  · 技术社区  · 14 年前

    [list a b c] 可与互换 {a b c} . 首选的方法是什么?在哪里 [列表a b c] 不符合…的行为 {a b c} ?

    2 回复  |  直到 14 年前
        1
  •  7
  •   bta    14 年前
    % 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
    

    [list ...] 窗体将在将变量放入字符串和 {...}

    基本上, {...} 把它里面的东西当作一个单一的、连续的字符串;特殊的性格 $ 永远不会被解释。这个 语句获取其参数并将它们连接在一起,用空格分隔。因此,如果您使用的项目是字符串文本,并且不包含任何需要解释的内容,那么这两种形式是相同的。

        2
  •  5
  •   Donal Fellows    14 年前

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

    然而,事情远不止这些。让我们潜得更深!

    在某些情况下你是这样做的 想使用 {…} 或者 "…" 表单,而这正是处理某些非文本的时候。特别是,如果您正在使用 tcom Tcl/Java (即Jacl或TclBlend)然后您将处理不完全遵循Tcl语义的对象。特别是,一些值会附加脆弱的对象;如果 Tcl_Obj 如果包含对值的引用,则其类型已更改(用Tcl的说法是闪烁的),那么对底层COM或Java对象的引用将被不可恢复地删除,垃圾收集器将在您完成该对象之前删除该对象。使用 [list …] 窗体以生成列表(以及类似 lindex 检索)将确保正确维护这些脆弱的内部表示,直到您不再需要它们。

    [list] 是你的朋友,即使在没有必要的时候(通常是这样)。

    另一个需要注意的情况是在生成回调时。

    通常,您希望在创建回调时某些值是已知的,而不是存储在执行回调时存在的某个变量中(我经常这样做 after , fileevent trace 太多了 使用创建的回调脚本 list (或其他一些生成列表的命令)比所有其他替代方法都快,因为Tcl脚本求值引擎可以证明它们没有替换,并直接将列表元素提供给命令调度器。当您只是将值传递给过程时,这是一个很大的优势,这被认为是回调的良好实践。