3

配列を渡し、配列を操作するコードのスニペットを以下に示しますが、新しいバージョンの配列を返すことはできません。

ここにスニペットがあります:

    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」に割り当てる方法を教えてください。

4

1 に答える 1

5

簡単な答えは次のとおりです。配列は値ではないため、プロシージャから配列を返すことはできません。配列は名前付きの値の独特の名前付きコレクションです。

これに対処するには、いくつかの方法があります。

通常のアプローチは、配列を名前で渡し、呼び出されたプロシージャで配列をその場で変更することです。たとえば、コード

proc foo {arrayName} {
    upvar 1 $arrayName ary
    incr ary(one)
}
set x(one) 1
foo x
puts $x(one)

プロシージャfooが呼び出し元のスコープ内の指定された配列内の特定の値を変更したため、"2" が出力されます。

呼び出し元が「その値」の代わりに配列の名前「x」を渡したことに注意してください (配列から値を抽出することはできませんが、以下を参照してください)。コマンドを使用して名前を付けupvarます。

もう 1 つの方法は、コマンドを使用array getarray setて配列からキーと値を抽出し、配列にキーと値をそれぞれ入力することです。例えば:

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にはマージ セマンティクスがあることに注意してください。ソース リストを使用して値を挿入/置換する前に、ターゲット配列を空にしません。

3 番目の (そしておそらく最良の) アプローチは、配列と同様にキー/値マップである辞書を使用することですが、それ自体が値であるため、他の値として自由に渡すことができます。これには Tcl 8.5 以降が必要です (Tcl 8.4 では、このコードのバックポートをパッケージの形で使用できます。dicts を使用すると、次のようになります。

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」が出力されます。

于 2012-12-02T00:36:26.150 に答える