将数组传递给tcl中的函数。只有upvar?

将数组传递给tcl中的函数。只有upvar?,tcl,Tcl,据我所知,在tcl中,如果要将命名数组传递给函数,必须通过被调用方主体内的upvar命令访问调用方的上部作用域。这是在tcl中传递数组的唯一方法吗?有很多方法,比如首先将它转换为列表(通过array get和array set)。为了了解其中的一些信息,以下是一些选项: 由Upvar提供 proc by_upvar {&arrName} { upvar 1 ${&arrName} arr puts arr(mykey) set arr(myotherkey

据我所知,在tcl中,如果要将命名数组传递给函数,必须通过被调用方主体内的
upvar
命令访问调用方的上部作用域。这是在tcl中传递数组的唯一方法吗?

有很多方法,比如首先将它转换为列表(通过
array get
array set
)。为了了解其中的一些信息,以下是一些选项:

由Upvar提供

proc by_upvar {&arrName} {
    upvar 1 ${&arrName} arr
    puts arr(mykey)
    set arr(myotherkey) 2
}
set myarr(mykey) 1
by_upvar myarr
info exists myarr(myotherkey) => true
  • 导致调用者看到对数组的更改
按数组获取/设置

proc by_getset {agv} {
    array set arr $agv
    puts arr(mykey)
    set arr(myotherkey) 2
    return [array get arr]
}
set myarr(mykey) 1
array set mynewarr [by_upvar myarr]
info exists myarr(myotherkey) => false
info exists mynewarr(myotherkey) => true
  • 导致调用者看到对数组的更改
  • 类似的机制可用于返回数组

如果只传入数组的值,则可以传入字典(提示:将数组序列化为字典值),并使用命令访问其中的值。但是如果您想要访问实时值,
upvar
绝对是最简单的。这也是一种非常快速的技术;在
upvar
本身完成后,它在变量访问期间编译为额外的指针遍历。

您的by\u upvar过程中的amperand是怎么回事?不是Tcl语法。@glenn jackman:“不是Tcl语法”?胡说一切都是tcl语法:-)。由于变量名可以是任何字符串,并且在其他一些语言中使用&来表示变量的地址,因此它提供了一种方便的半准自记录方式,将其指定为upvar的目标。有趣的是,这么多年来,我从来没有想过使用&;我通常使用u或fooVar(upvar$fooVar foo)。我通常使用“varname”。但是upvar命令中有一个错误:应该更新
upvar 1$&arrName arr
以说明错误(&a->${&a})。正如Bryan所指出的,它只是一种自我记录的方式,表示它是一个upvar变量名。尽管我不记得是谁给我的,但我还是从其他一些著名的Tcler那里复制了它。