Variables TCL/Expect变量vs$variable

Variables TCL/Expect变量vs$variable,variables,tcl,expect,Variables,Tcl,Expect,使用带或不带美元符号的变量的正确方法是哪一种?我认为变量(不含$)仅在变量声明期间使用(类似于Bash): 在所有其他情况下,当引用或使用(但未声明)变量时,正确的语法是$variable(带$): 但后来我找到了可以互换的代码,似乎这段代码正在工作: # using argv if {[array exists argv]} { puts "argv IS ARRAY" } else { puts "argv IS NOT AN ARRAY" } # using $argv if {

使用带或不带美元符号的
变量
的正确方法是哪一种?我认为
变量
(不含
$
)仅在
变量
声明期间使用(类似于Bash):

在所有其他情况下,当引用或使用(但未声明)变量时,正确的语法是
$variable
(带
$
):

但后来我找到了可以互换的代码,似乎这段代码正在工作:

# using argv
if {[array exists argv]} {
  puts "argv IS ARRAY"
} else {
  puts "argv IS NOT AN ARRAY"
}

# using $argv
if {[array exists $argv]} {
  puts "\$argv IS ARRAY"
} else {
  puts "\$argv IS NOT AN ARRAY"
}

# using argv
if {[string is list argv]} {
  puts "argv IS LIST"
} else {
  puts "argv IS NOT LIST"
}

# using $argv    
if {[string is list $argv]} {
  puts "\$argv IS LIST"
} else {
  puts "\$argv IS NOT LIST"
}
输出:

argv IS NOT AN ARRAY
$argv IS NOT AN ARRAY
argv IS LIST
$argv IS LIST
编辑回复@glenn jackman:

您的回复让我需要进一步研究,我发现TCL能够做一些“自我修改代码”或任何正确的名称,例如:

% set variableName "x"
x
% puts $x
can't read "x": no such variable
% set $variableName "abc"
abc
% puts $x
abc
% puts [set $variableName]
abc
%
%
%
%
%
%
% set x "def"
def
% puts $x
def
% puts [set $variableName]
def
%
现在你们的回答让问题变得明朗了,但还有一个问题。这是文件的摘录:

set varName ?value?
array exists arrayName
文档说明这两个函数都期望变量名(而不是值),换句话说,它期望的是
variable
,而不是
$variable
。因此,我假设(基于上述自修改代码),当我传递
$variable
而不是
variable
时,发生了变量替换(与上述代码完全相同)。但是如果
$variable
包含的内容既不是列表也不是数组(我在测试期间的参数是:param0 param1“param 2”param3),该怎么办呢。从这个角度来看,
$argv IS LIST
的输出是错误的。我错过了什么

编辑以回复@schlenk:

最后,我(希望)理解问题所在。我发现了TCL,这解释了(不仅仅是)这个问题。让我从这篇文章中指出一些明智的说法:

  • 在Tcl中,字符串表示什么取决于 操纵它
  • 在Tcl中,一切都是一个命令——正如您所看到的,没有 赋值运算符
  • 如果
    是一个命令,有两个参数
  • 命令名不是特殊类型,只是一个字符串
还确认这一声明:

“在Tcl中,值没有类型……它们的问题是它们是否可以用作给定的类型。” 命令
字符串为整数$a
表示:

  • “我可以将
    $a
    中的值用作整数吗?”
不是

  • $a
    中的值是否为整数”

  • “每个整数也是一个有效列表(一个元素)…因此可以 用作其中一个和两个string is命令将返回true(如下所示 数个其他值表示整数)。”

我相信这同样适用于
string is list
命令:

% set abc "asdasd"
asdasd
% string is list $abc
1
% string is alnum $abc
1
字符串是列表
返回1,因为
$abc
是字符串,也是一个元素列表等。在大多数教程中,以下代码段是声明和使用列表的正确方法:

% set list1 { 1 2 3 }
% lindex $list1 end-1
2
但是,当TCL中的所有内容都是字符串时,以下内容在我的经验中也起作用(如果我错了,请纠正我)


这取决于命令。某些Tcl命令需要变量名作为参数,如果它们需要修改变量的内容。其中包括:

  • 设置
  • 弗雷奇
  • 拉彭德
  • 增量
大多数但肯定不是所有的命令都希望获取变量的值

您需要检查相关命令,查看参数是否包括“varName”(或“dictionaryVariable”),或者参数是否命名为“string”、“list”等


存在一个使用
info
的示例,该示例采用varName参数:

% set argv {foo bar baz}
foo bar baz
% info exists argv              ;# yes the variable "argv" exists
1
% info exists $argv             ;# no variable named "foo bar baz"
0
% set {foo bar baz} "a value"   ;# create a variable named "foo bar baz"
a value
% info exists $argv             ;# so now that variable exists
1

这取决于命令。某些Tcl命令需要变量名作为参数,如果它们需要修改变量的内容。其中包括:

  • 设置
  • 弗雷奇
  • 拉彭德
  • 增量
大多数但肯定不是所有的命令都希望获取变量的值

您需要检查相关命令,查看参数是否包括“varName”(或“dictionaryVariable”),或者参数是否命名为“string”、“list”等


存在一个使用
info
的示例,该示例采用varName参数:

% set argv {foo bar baz}
foo bar baz
% info exists argv              ;# yes the variable "argv" exists
1
% info exists $argv             ;# no variable named "foo bar baz"
0
% set {foo bar baz} "a value"   ;# create a variable named "foo bar baz"
a value
% info exists $argv             ;# so now that variable exists
1

需要知道的重要一点是,Tcl中的
$x
只是命令
setx
的语法糖。因此,您可以在同一位置将Tcl代码中的任何
$x
转换为
[set x]
,以查看实际发生的情况

另一个重要的考虑因素是不变的价值观。Tcl值是不可变的,因此不能更改它们。您只需创建一个新的已更改值。但是您可以更改存储在变量中的值

这就是采用变量名的命令和采用值的命令之间的区别所在。如果命令要更改存储在变量中的值,它将使用变量名。例如
lappend
lset
append
等等。其他命令返回新值并将值作为参数,示例包括
lsort
lsearch
lindex

另一个重要的一点是,您实际上没有列表类型。您的字符串看起来像列表。这就是Tcl的
字符串是list
测试。这会产生一些后果,例如,您不能总是决定是使用字符串文字还是单项列表,因为它们通常是相同的。举例如下:

% set maybe_list a
% string is list $maybe_list
1
再加上Tcl几乎不受限制的变量名称,就像Glenn已经演示的那样,您可能会感到非常困惑。例如,这些都是有效的Tcl变量名,您不能将它们全部用于
$
快捷方式:

% set "" 1       ;# variable name is the empty string
1
% puts [set ""]
% set " " 1      ;# variable name is just whitespace
1
% puts [set " "]
1
% set {this is a list as variable name} 1 ;# a variable with a list name
1
% puts [set {this is a list as variable name}]
1
% set Δx 1 
1
% incr Δx
2
% puts [set Δx]
2

需要知道的重要一点是,Tcl中的
$x
只是命令
setx
的语法糖。因此,您可以在同一位置将Tcl代码中的任何
$x
转换为
[set x]
,以查看实际发生的情况

另一个重要的考虑因素是不变的价值观。Tcl值为im
% set maybe_list a
% string is list $maybe_list
1
% set "" 1       ;# variable name is the empty string
1
% puts [set ""]
% set " " 1      ;# variable name is just whitespace
1
% puts [set " "]
1
% set {this is a list as variable name} 1 ;# a variable with a list name
1
% puts [set {this is a list as variable name}]
1
% set Δx 1 
1
% incr Δx
2
% puts [set Δx]
2