【问题标题】:Accessing variables in TCL across scopes跨范围访问 TCL 中的变量
【发布时间】:2020-05-13 01:09:26
【问题描述】:

我正在尝试学习 tcl 脚本。我的要求很简单。我需要在 for 循环中的第二个 if 条件中访问数组“args”。我尝试了下面的代码。由于“argv”范围仅限于第二个 if 条件,因此在 for 循环中无法访问它

然后我尝试将 argv 声明为全局变量 -

数组集参数{}

就在第一个 if 条件的 ned 之下。即使将“args”声明为全局数组也没有帮助。

如何在下面的 for 循环中访问第二个 if contion 中的变量?

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]"
}

【问题讨论】:

  • 不调用变量args 是一个非常的好主意,除非它是过程的特殊最终形式参数,因为它不寻常(但有据可查)语义,否则你会混淆所有人。

标签: tcl


【解决方案1】:

对于您的原始代码,这是我得到的错误:

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)"
}

所以,范围并不是问题所在。不过你已经到了!

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

      猜你喜欢
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 2015-06-20
      • 1970-01-01
      • 1970-01-01
      • 2022-08-16
      • 2017-12-13
      • 1970-01-01
      相关资源
      最近更新 更多