Tcl 为什么proc局部变量会干扰全局变量

Tcl 为什么proc局部变量会干扰全局变量,tcl,Tcl,我使用的是TCL8.6 代码如下: proc unpack_list {list1 list2} { set i 0 foreach e $list2 { puts "globals=[info globals $e]" global $e set $e [lindex $list1 $i] incr i } } set l1 [list 10 20 30 40] set l2 [list a b c

我使用的是TCL8.6

代码如下:

proc unpack_list {list1  list2} {
    set i 0
    foreach e $list2 {
        puts "globals=[info globals $e]"
        global $e
        set $e [lindex $list1 $i] 
        incr i
    }
}

set l1 [list 10 20 30 40]
set l2 [list a b c e]
unpack_list $l1 $l2
puts $a
puts $b
puts $c
puts $e
puts [info globals ]
运行代码失败:

globals=
globals=
globals=
globals=
variable "e" already exists
    while executing
"global $e"
    (procedure "unpack_list" line 5)
    invoked from within
"unpack_list $l1 $l2"
    (file "tmp/1.tcl" line 13)
问题在于这一行:

set l2 [list a b c e]
如果我将“e”更改为“ee”,脚本运行良好:

globals=
globals=
globals=
globals=
10
20
30
40
tcl_rcFileName tcl_version argv0 argv tcl_interactive a ee b c auto_path env tcl_pkgPath tcl_patchLevel l1 argc l2 tcl_library tcl_platform

我的问题是:proc中的变量“e”不存在于全局命名空间中,它为什么会干扰全局变量“e”?

如果您阅读了
global
命令的描述,则说明该命令创建了链接到全局变量的局部变量。错误消息讲述了这个故事。局部变量已存在,并且
全局
拒绝更改其引用。否则会使局部变量神奇地改变值。

如果您阅读了
全局
命令的说明,则说明该命令创建了链接到全局变量的局部变量。错误消息讲述了这个故事。局部变量已存在,并且
全局
拒绝更改其引用。否则会使局部变量神奇地改变值。

要实现您似乎想要的功能,可以使用
upvar
命令。请尝试此版本的unpack_list命令:

proc unpack_list {list1 list2} {
    foreach v $list1 e $list2 {
        upvar #0 $e var
        set var $v
    }
}

这将不会导致全局变量名和局部变量名之间发生冲突。

要完成您想要的任务,可以使用
upvar
命令。请尝试此版本的unpack_list命令:

proc unpack_list {list1 list2} {
    foreach v $list1 e $list2 {
        upvar #0 $e var
        set var $v
    }
}

这永远不会造成全局变量名和局部变量名之间的冲突。

这就是问题所在,但不是如何解决问题。诚然,答案很窄,但问题是为什么会发生错误,而不是如何对将值推入全局变量的可疑任务进行编码。这就是问题所在,但不是如何修复。不可否认,这是一个非常狭隘的答案,但问题是为什么会发生错误,而不是如何编写将值推入全局变量的可疑任务。这是如何修复问题,而不是实际错误。这是如何修复问题,而不是实际错误。