跨作用域访问 TCL 中的变量
Accessing variables in TCL across scopes
我正在尝试学习 tcl 脚本。我的要求很简单。我需要在 for 循环的第二个 if 条件中访问数组 "args" 。我尝试了下面的代码。由于 "argv" 范围仅限于第二个 if 条件,因此在 for 循环
中不可访问
然后我尝试将 argv 声明为全局变量 -
array set args {}
就在第一个 if 条件的 ned 下方。即使在将 "args" 声明为全局数组后也无济于事。
如何在下面的for循环中访问第二个if条件中的变量?
if {$argc != 4} {
puts "Insufficient arguments"
exit 1
}
if { $::argc > 0 } {
set i 1
foreach arg $::argv {
puts "argument $i is $arg"
set args(i) arg
incr i
}
} else {
puts "no command line argument passed"
}
for {set x 0} { $x<2 } {incr x} {
puts "Arrray: [lindex $args $x]"
}
Tcl 默认不导入全局变量。您需要导入全局变量:
global args
set args(i) arg
有些人更喜欢在 proc 的顶部导入全局变量:
global args
if {$argc != 4} {
puts "Insufficient arguments"
exit 1
}
if { $::argc > 0 } {
set i 1
....
参见:https://www.tcl.tk/man/tcl8.7/TclCmd/global.htm
或者,您可以直接访问全局命名空间,实际上您已经在 ::argc
:
中使用该语法
set ::args(i) arg
对于您的原始代码,这是我得到的错误:
can't read "args": variable is array
while executing
"lindex $args $x"
("for" body line 2)
invoked from within
"for {set x 0} { $x<2 } {incr x} {
puts "Arrray: [lindex $args $x]"
}"
(file "main.tcl" line 20)
在 Tcl 中,数组不是列表。你必须写
for {set x 0} { $x<2 } {incr x} {
puts "Arrray: $args($x)"
}
但后来我明白了:
can't read "args(0)": no such element in array
while executing
"puts "Arrray: $args($x)""
("for" body line 2)
invoked from within
"for {set x 0} { $x<2 } {incr x} {
puts "Arrray: $args($x)"
}"
(file "main.tcl" line 20)
这里有几个问题。您正在设置从索引 1 开始的数组元素,但从索引 0 开始读取它们。所以让我们将其更正为 0:
set i 0
但您在元素设置中还遗漏了一些 $
:
set args($i) $arg
看起来好多了。最终代码:
if {$argc != 4} {
puts "Insufficient arguments"
exit 1
}
if { $::argc > 0 } {
set i 0
foreach arg $::argv {
puts "argument $i is $arg"
set args($i) $arg
incr i
}
} else {
puts "no command line argument passed"
}
for {set x 0} { $x<2 } {incr x} {
puts "Arrray: $args($x)"
}
所以,范围并不是问题所在。不过你快到了!
我正在尝试学习 tcl 脚本。我的要求很简单。我需要在 for 循环的第二个 if 条件中访问数组 "args" 。我尝试了下面的代码。由于 "argv" 范围仅限于第二个 if 条件,因此在 for 循环
中不可访问然后我尝试将 argv 声明为全局变量 -
array set args {}
就在第一个 if 条件的 ned 下方。即使在将 "args" 声明为全局数组后也无济于事。
如何在下面的for循环中访问第二个if条件中的变量?
if {$argc != 4} {
puts "Insufficient arguments"
exit 1
}
if { $::argc > 0 } {
set i 1
foreach arg $::argv {
puts "argument $i is $arg"
set args(i) arg
incr i
}
} else {
puts "no command line argument passed"
}
for {set x 0} { $x<2 } {incr x} {
puts "Arrray: [lindex $args $x]"
}
Tcl 默认不导入全局变量。您需要导入全局变量:
global args
set args(i) arg
有些人更喜欢在 proc 的顶部导入全局变量:
global args
if {$argc != 4} {
puts "Insufficient arguments"
exit 1
}
if { $::argc > 0 } {
set i 1
....
参见:https://www.tcl.tk/man/tcl8.7/TclCmd/global.htm
或者,您可以直接访问全局命名空间,实际上您已经在 ::argc
:
set ::args(i) arg
对于您的原始代码,这是我得到的错误:
can't read "args": variable is array
while executing
"lindex $args $x"
("for" body line 2)
invoked from within
"for {set x 0} { $x<2 } {incr x} {
puts "Arrray: [lindex $args $x]"
}"
(file "main.tcl" line 20)
在 Tcl 中,数组不是列表。你必须写
for {set x 0} { $x<2 } {incr x} {
puts "Arrray: $args($x)"
}
但后来我明白了:
can't read "args(0)": no such element in array
while executing
"puts "Arrray: $args($x)""
("for" body line 2)
invoked from within
"for {set x 0} { $x<2 } {incr x} {
puts "Arrray: $args($x)"
}"
(file "main.tcl" line 20)
这里有几个问题。您正在设置从索引 1 开始的数组元素,但从索引 0 开始读取它们。所以让我们将其更正为 0:
set i 0
但您在元素设置中还遗漏了一些 $
:
set args($i) $arg
看起来好多了。最终代码:
if {$argc != 4} {
puts "Insufficient arguments"
exit 1
}
if { $::argc > 0 } {
set i 0
foreach arg $::argv {
puts "argument $i is $arg"
set args($i) $arg
incr i
}
} else {
puts "no command line argument passed"
}
for {set x 0} { $x<2 } {incr x} {
puts "Arrray: $args($x)"
}
所以,范围并不是问题所在。不过你快到了!