如您所知,Tcl 和 C++ 对值和类型有非常不同的方法。特别是,Tcl 几乎完全通过对类型可变的值的逻辑不可变引用来工作,这与 C++(以及许多其他语言,公平地说)非常不同。真正的 mutator 操作(例如增量)实际上会创建副本。
另一个关键区别是在 Tcl 中,一切都是通过执行命令来完成的。这包括创建其他命令。那proc
?这是对命令(称为proc
)的调用,该命令立即创建具有给定名称、参数和主体的过程。没有什么比声明更重要的了;当你告诉代码让它发生时,事情就会发生。这听起来比实际要复杂得多。
如何将列表值传递给过程
假设您Name
是一个列表,然后您将传递整个列表值(通过不可变引用,如此快速和安全),并且里面的代码可以做它想做的任何事情而不会影响外部世界。然后你会这样写:
# Define
proc employee_data {Name ...} {
lassign $Name A B C
# ... do other processing ...
}
# Call
set Name {Aitem Bitem Citem}
employee_data $Name ...
您还可以使用立即定义的数据进行调用;Tcl 对此非常满意:
employee_data {Aitem Bitem Citem} ...
传入字典值
字典与列表非常相似,不同之处在于它们将键映射到值而不是序列。
proc employee_data {Name ...} {
dict with Name {}
# ...
}
set Name {A "foo" B "bar" C "grill"}
employee_data $Name ...
您还可以将(关联)数组内容的副本作为字典值传递,如下所示:
employee_data [dict get Name] ...
传递参考
但是假设你想改变外部世界!为此,您必须传递要更改的变量的名称。然后,您可以使用upvar
将局部变量绑定到调用者的变量,以便您可以进行修改并将它们粘贴。该upvar
命令实际上可以让您按名称进行调用,并且非常神奇。
proc employee_data {NameVar ...} {
upvar $NameVar name
# ... accessing $name as if it was whatever variable was passed ...
}
set Name {Aitem Bitem Citem}
# Note: *not* $Name! We want the name, not the contents!
employee_data Name ...
您可以将内置命令想象为set
和incr
像这样工作。这也适用于关联数组。