我将在这里使用Perl作为比较:
$foo = 5;
print $foo;
Run Code Online (Sandbox Code Playgroud)
将变量设置$foo为5,然后打印变量的内容($foo始终作为访问的通知$foo).
在Tcl中:
set foo 5
puts $foo
Run Code Online (Sandbox Code Playgroud)
与Perl对应物做同样的事情.
为什么Tcl不用"$"设置变量,但需要"$"来访问变量?为什么程序也是如此(例如proc bar {spam eggs} {...})?对我来说,Tcl代码看起来像这样(在伪代码中):
"foo" = 5 # Setting a string?
puts $foo # "$foo" is not defined.
Run Code Online (Sandbox Code Playgroud)
(我的评论只反映了似乎正在发生的事情,而不是正在发生的事情).
我要补充的另一点是清晰度:
set foo foo
Run Code Online (Sandbox Code Playgroud)
是的,我可以随时做set foo "foo",但不是set $foo foo更一致吗?
据我所知,"foo"可以是变量或字符串,具体取决于具体情况,如我上一个例子(set foo foo= set var string)所示,但我没有得到这种语法(也许是因为我习惯了Python .. .)
kos*_*tix 14
我认为原来的Tcl只有set命令,所以获取变量"foo"内容的唯一方法就是调用set foo.但随着Tcl进入通用脚本语言的领域(回想一下,Tcl被设想为一种可嵌入的语言,你使用薄层Tcl而不是用C语言编写的编译组件,因此预计不会使用大量变量),认为$ varname语法糖是有用的,所以它被添加了.
换句话说,Tcl不像Perl那样使用"$",其中"$"表示"将后面的任何内容解释为标量",Tcl中的"$"也不表示变量.相反,它只是一个语法糖,"给我一个变量的值,其名称由紧接着的单词给出".
kos*_*tix 13
好吧,我决定对原始问题的最后几点进行评论,但评论超出了限制,所以即使它没有解决指出的问题,我也会将其作为答案发布.我希望它能澄清一些似乎在问题中隐含的内容.
关于一致性的说明set foo foo:你以某种错误的方式接近Tcl.Tcl与Perl或Python完全不同,因为它几乎没有语法(实际上,就像LISP一样)."set foo foo"不是设置变量的语法,因为它可能是另一种语言,它是对当前名为"set" 的命令的调用,并传递两个参数 - "foo"和"foo"; 它是在"set"命令名下注册的任何内容,决定变量的名称是什么以及将其设置为什么值.同样,循环命令不是语法,而是命令.真的,值得停下来思考一下
for {set i 0} {$i < 10} {incr i} {
puts $i
}
Run Code Online (Sandbox Code Playgroud)
不仅仅是一个异想天开的语言设计师的想法,而是使用花括号或"普通"括号,例如C语言.相反,这里Tcl解析器解析出五个单词,将第一个单词作为命令的名称,查找它,并将其余的字传递给它; 它的实施for,其解释的{set i 0},{$i < 0}等等,并适当地执行它们.语法仅用于指定如何从输入的字符流中解析出单词.而且由于所有内容都是使用命令实现的,因此您的命令与内置命令的行为没有区别; 这允许您创建与foror 一样强大的自定义命令switch(类似于LISP中的宏).在另一种语言中,这将等于以任意方式扩展sytnax的能力.
当这个想法"点击"时,Tcl将不再显得奇怪.而且这个属性使得Tcl易于扩展(并且可嵌入):因为你从C端提供的命令与所有内置命令完全相同.