数组是否返回引用或值?

时间:2013-06-12 14:56:39

标签: tcl

array get返回什么,引用或值?我有一个列表作为值列表,并且必须经常修改列表。有效的方法是什么?

1 个答案:

答案 0 :(得分:9)

首先是一些基础知识。 Tcl没有参考。没有任何。所以tcl中的所有命令总是返回值。

因此,对第一个问题的简单回答是它返回一个值。

要深入研究tcl的值语义如何工作的细节,有两种方法可以看待事物。

首先,严格按照语言规范查看语言。换句话说,用户/程序员的观点。从这个角度来看,tcl只能做一件事:进程字符串。 tcl中的所有内容都是一个字符串。从技术上讲,你可以说tcl具有极强的价值语义和几乎没有任何参考语义(有点像C,除了C更喜欢数字(甚至字符串只是C中数字的数组))。

如果是这样,列表是什么?那么,从这个角度来看,列表只不过是特殊格式的字符串。如果字符串看起来像列表,那么它就是一个列表。如果不是,这是一个无效的列表。在任何一种情况下,它们都是字符串。数字也是如此。

那么,什么是数组呢?好吧,阵列有点特别。文件是特殊的,网址是特殊的。要获取文件的值(内容),请使用openread以及gets等命令。要获取数组的值,可以使用array get等命令和特殊$array_name(key)语法。您可以将数组视为一种内置的简单键值对数据库。它们的行为与tcl中的常规变量不同,因为$array_name会产生语法错误,而不是数组值(内容)的字符串表示形式。但array get允许将数组序列化为字符串表示形式,因此对于每个字符串的观点来说,所有数据都是很好的。

第二种观点是语言是如何实现的。在C级别,tcl中的所有内容都是一个对象,变量/值总是作为指针传递。 Tcl竭尽全力以尽可能快的访问和修改形式存储数据。所以一个列表,而从高级视图只是一个字符串格式约定,在低级别实际上实现与字符串不同。这允许tcl快速处理列表,数组和数字。但是如果你明确要求tcl将列表或数组或数字视为字符串,那么tcl别无选择,只能将对象解析为字符串,然后将该字符串重新解析为本机对象类型。这被称为闪烁,它消耗了大量的CPU周期。

Tcl还实现了引擎上的修改。因此,返回列表或字符串的完整副本实际上不会导致在内存中创建对象的另一个副本。只有在尝试修改返回值时才会创建副本。

所以你的第二个问题的答案是如果你关心速度(正则表达式,字符串优先等),避免使用字符串命令处理列表数组。使用list命令处理列表和字符串命令以处理字符串。有些情况下你无法避免它,并且有些情况下字符串命令可能更容易,速度并不重要但通常尽量避免闪烁。获得这是一个好习惯。

鉴于上述所有情况,修改列表的最有效方法是在阵列上使用list命令(lsetlrange等)。例如,要修改数组“foo”中列表“bar”中的第二个元素,我们会这样做:

lset foo(bar) 1 "new value"