グローバルを使用せずにbashで配列を返すにはどうすればいいですか? 質問する

グローバルを使用せずにbashで配列を返すにはどうすればいいですか? 質問する

配列を作成する関数があり、その配列を呼び出し元に返したいとします。

create_array() {
  local my_list=("a", "b", "c")
  echo "${my_list[@]}"
}

my_algorithm() {
  local result=$(create_array)
}

これだと、展開された文字列しか取得できません。グローバルなものを何も使用せずに、my_list を「返す」にはどうすればよいのでしょうか?

ベストアンサー1

Bashバージョン4.3以降では、名前参照呼び出し元は配列名を渡し、呼び出し先は名前参照を使用して名前付き配列に値を設定できるようになります。間接的に

#!/usr/bin/env bash

create_array() {
    local -n arr=$1             # use nameref for indirection
    arr=(one "two three" four)
}

use_array() {
    local my_array
    create_array my_array       # call function to populate the array
    echo "inside use_array"
    declare -p my_array         # test the array
}

use_array                       # call the main function

出力を生成します:

inside use_array
declare -a my_array=([0]="one" [1]="two three" [2]="four")

関数に既存の配列を更新させることもできます:

update_array() {
    local -n arr=$1             # use nameref for indirection
    arr+=("two three" four)     # update the array
}

use_array() {
    local my_array=(one)
    update_array my_array       # call function to update the array
}

これはよりエレガントで効率的なアプローチです。コマンド置換は必要ありません $()呼び出される関数の標準出力を取得します。関数が複数の出力を返す場合にも役立ちます。出力の数と同じ数の名前参照を使用できます。


これがBash マニュアルnameref について次のように述べています:

変数に nameref 属性を割り当てるには、declare または local 組み込みコマンド (Bash 組み込みコマンドを参照) に -n オプションを使用して、nameref または別の変数への参照を作成します。これにより、変数を間接的に操作できます。nameref 変数が参照、割り当て、設定解除、または属性の変更 (nameref 属性自体の使用または変更を除く) が行われるたびに、操作は実際には nameref 変数の値で指定された変数に対して実行されます。nameref は、シェル関数内で、関数に引数として渡される名前を持つ変数を参照するためによく使用されます。たとえば、変数名がシェル関数の最初の引数として渡される場合、

関数内で -n ref=$1 を宣言すると、最初の引数として渡された変数名を値とする名前参照変数 ref が作成されます。ref への参照と割り当て、およびその属性の変更は、$1 として渡された名前を持つ変数への参照、割り当て、および属性の変更として扱われます。

おすすめ記事