【问题标题】:passing arrays to functions in tcl. Only upvar?将数组传递给 tcl 中的函数。只有upvar?
【发布时间】:2011-03-31 14:34:24
【问题描述】:

据我了解,在 tcl 中,如果要将命名数组传递给函数,则必须通过被调用者正文中的 upvar 命令访问调用者的上层范围。这是在 tcl 中传递数组的唯一方法吗?

【问题讨论】:

    标签: tcl


    【解决方案1】:

    正如 Michael 所指出的,有几种方法,还有一个讨论它的 wiki 页面。只是为了在这里获得一些信息,一些选项是:

    作者: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
    
    • 导致调用者看到数组的变化
    • 类似的机制可以用来返回一个数组

    【讨论】:

    • 你的 by_upvar 过程中的 & 是怎么回事?不是 Tcl 语法。
    • @glenn jackman:“不是 tcl 语法”?废话!一切都是 tcl 语法:-)。由于变量名可以是任何字符串,并且在其他一些语言中使用 & 来表示变量的地址,因此它提供了一种方便的半准自文档化方式,将其指定为 upvar 的目标。有趣的是,这么多年我从来没想过使用 &;我通常使用 _ 或 fooVar (upvar $fooVar foo)。
    • 好的,是的。我通常使用“varname”。但是 upvar 命令有一个错误:应该是upvar 1 $&arrName arr
    • 已更新以解决错误 (&a -> ${&a})。正如 Bryan 所指出的,它仅用作一种自我记录的方式,表示它是一个 upvar'd 变量名。不过我不能把它归功于它,因为我从其他一些著名的 Tcler 那里复制了它,虽然我不记得是谁。
    【解决方案2】:

    还有other ways,比如先转换成列表(通过array getarray set)。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-24
        • 2020-07-28
        • 1970-01-01
        相关资源
        最近更新 更多