Arrays TCL:如何返回数组?

Arrays TCL:如何返回数组?,arrays,return,tcl,Arrays,Return,Tcl,请在下面找到一段代码,它传递数组,操纵数组,但我无法返回新版本的数组 以下是片段: proc get_mroute_active { &multicast } { upvar ${&multicast} MULTICAST ; set group -1 ; set src -1 ; set mcast_

请在下面找到一段代码,它传递数组,操纵数组,但我无法返回新版本的数组

以下是片段:

    proc    get_mroute_active { &multicast }   {
        upvar   ${&multicast} MULTICAST ;

                set group   -1 ;
                set src -1 ;
                                set     mcast_group_source_id   -1 ;
                                set     MULTICAST($mcast_group_source_id,id) $mcast_group_source_id ;
                                set     MULTICAST($mcast_group_source_id,mcast_group) $group ;
                                set     MULTICAST($mcast_group_source_id,mcast_source) $src ;

        puts    [array size MULTICAST] ;
    parray  MULTICAST ;
}


array set     multicast { } ;

get_mroute_active [array get multicast] ;
puts    [array size multicast] ;
parray multicast ;
代码的输出是:

3
MULTICAST(-1,id)           = -1
MULTICAST(-1,mcast_group)  = -1
MULTICAST(-1,mcast_source) = -1
0

您能告诉我如何将“MULTICAST”变量分配给“MULTICAST”吗?

简单的回答是:不能从过程返回数组,因为数组不是值-它们是命名值的特殊命名集合

有几种方法可以解决这个问题:

通常的方法是按名称传递数组,并让被调用的过程修改数组。例如,代码

proc foo {arrayName} {
    upvar 1 $arrayName ary
    incr ary(one)
}
set x(one) 1
foo x
puts $x(one)
将打印“2”,因为过程
foo
修改了调用者作用域中指定数组中的特定值

请注意,调用方如何传递数组的名称“x”,而不是“其值”(因为您无法从数组中提取值;请参见下文),然后被调用的过程使用命令通过其名称将局部变量绑定到该数组

另一种方法是使用命令从数组中提取键和值,并分别用键和值填充数组。例如:

set x(one) 1
set x(two) 2
array set another [array get x]
parray another
将打印

another(one) = 1
another(two) = 2
给定一个数组,
array get
命令返回一个带键的平面列表及其各自的值交错。通过这种方式,您可以从过程返回数组的内容,然后让调用者对这些内容执行任何操作,例如,使用
array set
命令填充其作用域中的另一个数组(可能与最初传递给该过程的数组相同)

请注意,
array set
具有合并语义:在使用源列表插入/替换其值之前,它不会清空目标数组

第三种(可能是最好的)方法是使用与数组一样的键/值映射,但它们本身是值,因此它们可以作为其他值自由传递。这需要Tcl 8.5或更高版本(在Tcl 8.4中,您可以以包的形式使用。使用
dict
s,您可以得到如下结果:

proc foo d {
    dict set d one 2
    return $d
}
set x [dict create]
dict set x one 1
set y [foo $x]
puts $y

它会打印“one 2”,因为过程修改了原始字典,然后返回它,然后调用者将它分配给另一个变量。

谢谢你kostix,我也尝试过,但当我将数组作为参数传递时,我放了“$”,这是我的错误:)谢谢你的帮助:)@user690182,请阅读更多关于变量名及其值和美元符号的背景。请注意,代码风格通常是怪异的,暗示它是由一个不想花时间掌握新工具的C++程序员编写的。如果Tcl中的命令调用已经被新行分隔,则不需要用分号终止,而且在经验丰富的Tcl程序员编写的代码中,您不会看到分号的大量使用。在参数的名称中放一个<代码>和代码>是“KeWL”,因为它使它看起来像C++中的引用,但是TCL没有引用,所以这只是误导。@ KOSTiX -老实说,我用我的代码中的很多来指示传入的变量将是UVAVID。我不知道我最初是从哪里得到这个想法的(我想这是我90年代在tcl会议上遇到的核心人物之一),但我一直都很喜欢它。