列表在通过过程传递时成为嵌套列表

List become a nested list when passed through a procedure

我是一个新手,刚学了一些TCL,最近遇到一个莫名其妙的TCL内部流程,无法解释。我有以下代码:

proc print_items{args} {
    foreach item $args {
        puts $item
    }
}

set arr "A B C D"
print_items $arr

我期待的结果是:

A
B
C
D

但它是:

A B C D

经过仔细检查。我注意到 $args 不是我认为的平面列表,而是

> puts $args
{A B C D}
> llength $args
1

这意味着 $args 本身必须被包装在另一个列表中,即 $args 在被过程接收时必须是这样的:{{A B C D}}

所以我的问题是:为什么TCL在print_items内部传递时将一个已经形成的列表包装在另一个列表中?这与我做过的其他编程语言非常不同。在什么情况下参数会被包装在另一个数据结构中(即:在另一个列表、字典、数组等中)?

过程参数中的关键字"args"具有特殊含义。它将所有参数收集到一个 tcl 列表中。例如:

proc foo { param1 param2 args } {
    # here:
    #     $param1 = alice
    #     $param2 = bob
    #     $args = {alice1 bob1 alice2 bob2}
}
foo alice bob alice1 bob1 alice2 bob2

因此,您的问题的答案是:不要使用特殊词 "args" 作为 prodecure 参数,因为它是以特殊方式处理的。尝试使用任何其他名称作为过程 agrument。