Bashのマニュアルは次のように言います:
パラメータは値を格納するエンティティです。
変数は名前で表されるパラメータです。
パラメータに値が割り当てられている場合は、パラメータが設定されます。
下付き文字が割り当てられている場合、配列変数は設定されたと見なされます。
配列変数は変数ですか、それともパラメータですか?
それでは、割り当て時に配列変数が設定されていると見なされないのはなぜですか()
?
$ ar=()
$ echo ${ar-This is a new value}
This is a new value
ありがとうございます。
答え1
Inはbash
inと同じですksh
。ここで$var
は配列$var
であり、実際にはの略語です${var[0]}
。
だから:
var=([1]=whatever [2]=blah)
${var+set}
に拡張されずset
、インデックス0を持つ要素がない[[ -v var ]]
ため、falseを返します。 )。$var
bash
ksh
bash
(少なくとも4.3以降)では、次のように変数を配列として宣言するとき:
typeset -a var
var
最初は設定されていません。空のリストに設定されていませんでした。ではエラー4.3
がtypeset -p var
返されます。バージョン4.2以下では、以下を出力します。
declare -a a='()'
(配列を宣言すると空のリストが割り当てられるのと同じですzsh
。)
4.4では、出力は次のようになります。
declare -a var
したがって、4.3以降に設定されていない(しかし宣言された)配列は、空のリストが割り当てられた配列と同じではありません。
しかし、プログラム的に2つの違いを区別することは困難です。しかし、実際には、これらの区別はあまり役に立ちません。おそらく、配列にいくつの要素があるかどうかを知りたいでしょう。
((${#array[@]})) || echo array has no element
より良い配列設計を備えたシェルについては、およびzsh
をrc
参照fish
してください。yash
答え2
設定されていない場合、構文は${var-foo}
次に展開されます。foo
var
または空。空の配列がまさにそれです。
あなたが引用したように:
下付き文字が割り当てられている場合、配列変数は設定されたと見なされます。
お客様のサイトの例()では、下付きar=()
文字に値を割り当てません。
答え3
配列全体をテストする正しい方法は次のとおりです。
[[ ${ar[@]+set} == set ]] && echo "array has a value may be a null"
インデックス0の値のテストを作成しています。これら2つは同じです。
${ar+set}
${ar[0]+set}
ただし、どちらも配列全体ではなく、インデックス0の配列が設定されているかどうかをテストします。これがまさにあなたが意味するものだと思います。
しかし、あなたの質問に:割り当て()の場合、配列が設定されていないのはなぜですか?
持っているからいいえnull 以外のすべての値を配列インデックスに割り当てます。
一部のインデックス(および配列)を設定するには、次のものが必要です。
$ declare -a ar=([3]="value")
でも:
$ declare -a ar=([3]="")
zsh(shまたはkshシミュレーションでも)は、テストされたすべてのシェル(通常特殊シェル)のうち、唯一の配列を次のように宣言します。
$ unset ar; typeset -a ar=(); echo $(typeset -p ar) ${ar[@]+set}
コメントの質問:
ありがとうございます。ここで ar[@] を ar[*] に変更できますか?配列変数ですか?
いいえ、anは"${ar[*]}"
すべての配列値の文字列連結です。
ただし、この特定の拡張では、「${ar[*]+set}」は同じです。
マニュアルから(配列へ):
下付き文字が@または*の場合、単語はnameのすべてのメンバーに展開されます。