37

連想配列は、グローバルである必要がある関数本体内で宣言された場合、デフォルトでローカルであるように見えます。次のコード

#!/bin/bash

f() {
    declare -A map
    map[x]=a
    map[y]=b
}

f
echo x: ${map[x]} y: ${map[y]}

出力を生成します:

x:  y:

この間

#!/bin/bash

declare -A map

f() {
    map[x]=a
    map[y]=b
}

f
echo x: ${map[x]} y: ${map[y]}

出力を生成します:

x: a y: b

関数内でグローバル連想配列を宣言することは可能ですか? または、どのような回避策を使用できますか?

4

5 に答える 5

34

送信者: Greg Wooledge
送信者: 2011 年 8 月 23 日 (火) 06:53:27 -0700
件名: Re: YAQAGV (グローバル変数に関するもう 1 つの質問)

bash 4.2 では、「declare -g」を追加して、関数内からグローバル変数を作成します。

グレッグありがとう!ただし、Debian Squeeze にはまだ Bash 4.1.5 があります。

于 2012-05-29T21:14:24.077 に答える
9

4.2 では "declare -g" が追加されていますが、連想配列にはバグがあるため、(まだ) 質問に答えていません。以下は、私のバグ レポートと、次のリリースで修正が予定されているという Chet の確認です。

http://lists.gnu.org/archive/html/bug-bash/2013-09/msg00025.html

しかし、配列を宣言して同時に初期値を割り当てるのではなく、最初に配列を宣言してから割り当てを行う代わりに、偶然にも回避策を見つけました。つまり、次のことはしないでください。

declare -gA a=([x]=1 [y]=2)

しかし、これは代わりに:

declare -gA a; a=([x]=1 [y]=2)
于 2014-01-16T01:49:03.583 に答える
7

あなたはすでにdeclare -gであなた自身の質問に答えています。バージョン 4.2 未満の bash での回避策は、関数の外側で配列を宣言することです。

f() {
   map[y] = foo
}

declare -A map
foo
echo "${map[y]}"
于 2012-05-29T21:18:39.940 に答える
2

この例では、bash の関数内でグローバル連想配列変数を宣言しています。

set -euf +x -o pipefail # There is no place for implicit errors in this script.

function init_arrays(){
    # FYI. Multiple array declarations are not a problem. You can invoke it multiple times.

    # The "-gA" switch is the trick for the global array declaration inside a function.
    declare -gA my_var
}

function do_work(){
    init_arrays

    my_var[$1]=OPPA
}

do_work aa

echo ${my_var[aa]}
echo It is expected to get OPPA value printed above

GNU bash、バージョン 4.4 でテスト済み...

重要な注意事項。
このdeclare -Aコマンドは、実際には連想配列をすぐには作成しません。変数名に属性を設定するだけで、連想配列として名前に割り当てることができます。配列自体は、最初の代入 (!!!) まで存在しません。

(このスレッドで完全に機能する例を見たかったのですが、申し訳ありません。)

于 2020-02-21T18:32:22.067 に答える