TCL:数组是变量的集合

TCL : array is a collection of variables

我正在尝试了解 TCL 数组和 TCL 字典之间的区别

我得到一个声明:-“TCL 数组是变量的集合,而 TCL 字典是值的集合”

谁能解释一下它的实际含义。编程例子看懂一样就好了

谢谢

对于数组,这些实际上是三个独立的变量。

set my_array(a)  1
set my_array(b)  2
set my_array(c)  3

每个变量单独存在:

info exists my_array(a)  --> 1
info exists my_array(b)  --> 2
info exists my_array(c)  --> 3
puts "$my_array(a) $my_array(b) $my_array(c)"  --> 1 2 3

名称my_array也被认为是存在的,但实际上是三个独立变量的集合的特殊名称。它并不是真正的具有自己 value.

的常规变量
info exists my_array --> 1
puts $my_array --> can't read "my_array": variable is array

有了一本字典,就有一个变量。变量的值表示 key/value 对。

set my_dict "a 1 b 2 c 3"
info exists my_dict    --> 1
info exists my_dict a  --> wrong # args: should be "info exists varName"
puts $my_dict          --> {a 1 b 2 c 3}
dict keys $my_dict     --> {a b c}
dict get $my_dict a    --> 1
dict values $my_dict   --> {1 2 3}

在此示例中,my_dict{a 1 b 2 c 3}。您可以将 $my_dict 作为参数传递给 proc,该值由 proc 使用。您还可以 return 来自 proc 的命令。您不能以相同的方式对数组执行此操作。

除了

字典可以作为值传递给 proc

proc printItByValue {value} {
    puts $value
}

set myDict [dict create a 1 b 2 c 3]    ;# just another way to create a dict

printItByValue $myDict                  ;# => a 1 b 2 c 3

数组必须以不同的方式传递给 proc:

array set myArray {a 1 b 2 c 3}         ;# just another way to populate an array

printItByValue $myArray                 ;# error as shown by Chris
printItByValue myArray                  ;# only prints the string "myArray"

我们可以提取数组内容并将其作为列表传递给 proc:

proc printArrayByValue {arrayContents} {
    array set localArray $arrayContents
    parray localArray
}

printArrayByValue [array get myArray]
localArray(a) = 1
localArray(b) = 2
localArray(c) = 3

parray 是一个方便的实用程序,用于漂亮地打印数组。 或者,我们可以使用 upvar 命令将传递的 变量 name link 传递给调用者的堆栈框架。

proc printArrayByName {varName} {
    upvar 1 $varName localArray
    parray localArray
}

printArrayByName myArray          ;# same output as above

请注意,这些过程使用 local 名称打印出数组。为了让数组以相同的名称打印,我们可以对 link 的 local 变量做这个棘手的事情 caller's 变量同名:

proc printArrayByName {varName} {
    upvar 1 $varName $varName
    parray $varName
}

printArrayByName myArray          ;# same output as above
myArray(a) = 1
myArray(b) = 2
myArray(c) = 3

最大的区别之一是您可以 trace add variable 数组的元素,而您可以将字典传递给过程并从过程中 return 它,而无需 fiddle 周围有 upvararray get/array set.

proc didSetOnVarElement {name1 name2 op} {
    puts "did $op on ${name1}($name2)"
}
trace add variable x(a) write didSetOnVarElement
set x(a) 1
set x(b) 2
incr x(a)
# Try comparing the output of that with what you get when you set a trace on the whole of x

跟踪数组元素确实有用,尤其是在 Tk 中。所以可以便宜地来回传递东西。但是你不能把它们放在一起:值在 Tcl 中没有身份,而变量却有(而且正是那个身份——那个名字——使它们成为可修改和可追踪的实体,同时防止它们被随意传递)。