首先是一些基础知识.Tcl没有参考.没有任何.所以tcl中的所有命令总是返回值.
所以对你的第一个问题的简单回答是它返回一个值.
要深入研究tcl的值语义如何工作的细节,有两种方法可以看待事物.
首先,严格按照语言规范看到的语言.换句话说,用户/程序员的观点.从这个角度来看,tcl只能做一件事:进程字符串.tcl中的所有内容都是一个字符串.从技术上讲,你可以说tcl具有极强的价值语义,几乎没有任何参考语义(类似于C,除了C更喜欢数字(甚至字符串只是C中的数字数组)).
如果是这样,列表是什么?那么,从这个角度来看,列表只不过是特殊格式的字符串.如果字符串看起来像列表,那么它就是一个列表.如果不是,这是一个无效的列表.在任何一种情况下,它们都是字符串.关于数字也可以这么说.
那么,什么是阵列呢?好吧,阵列有点特别.文件是特殊的,网址是特殊的.要获取文件的值(内容),请使用open
和 read
和之类的命令gets
.要获取数组的值,请使用类似命令array get
和特殊$array_name(key)
语法.您可以将数组视为一种内置的简单键值对数据库.它们在tcl中的行为不像常规变量,因为$array_name
产生语法错误而不是数组值(内容)的字符串表示.但是array get
允许将数组序列化为字符串表示形式,因此对于每个字符串的观点来说,一切都很好.
第二种观点是语言的实现方式.在C级别,tcl中的所有内容都是一个对象,变量/值总是作为指针传递.Tcl竭尽全力以尽可能快的访问和修改形式存储数据.所以一个列表,而从高级视图只是一个字符串格式约定,在低级别实际上实现与字符串不同.这允许tcl快速处理列表,数组和数字.但是如果你明确要求tcl将列表或数组或数字视为字符串,那么tcl别无选择,只能将对象解析为字符串,然后将该字符串重新解析为本机对象类型.这被称为闪烁,它消耗了大量的CPU周期.
Tcl还实现了引擎上的修改.因此,返回列表或字符串的完整副本实际上不会导致在内存中创建对象的另一个副本.仅当您尝试修改返回的值时才会创建副本.
所以你的第二个问题的答案是如果你关心速度(regexp,字符串优先等),避免使用字符串命令处理列表数组.使用list命令处理列表和字符串命令以处理字符串.有些情况下你无法避免它,并且有些情况下字符串命令可能更容易,速度并不重要但通常尽量避免闪烁.获得这是一个好习惯.
在所有上述的光,来修改列出了最有效的方式是使用列表命令(lset
,lrange
阵列上等等).例如,要修改数组"foo"中列表"bar"中的第二个元素,我们会这样做:
lset foo(bar) 1 "new value"
Run Code Online (Sandbox Code Playgroud)