배열 변수에 "()" 값이 할당되면 설정된 것으로 간주되지 않는 이유는 무엇입니까?

배열 변수에 "()" 값이 할당되면 설정된 것으로 간주되지 않는 이유는 무엇입니까?

Bash 매뉴얼은 다음과 같이 말합니다:

매개변수는 값을 저장하는 엔터티입니다.

변수는 이름으로 표시되는 매개변수입니다.

매개변수에 값이 할당된 경우 매개변수가 설정됩니다.

아래 첨자가 할당된 경우 배열 변수는 설정된 것으로 간주됩니다.

배열변수는 변수인가요 아니면 매개변수인가요?

그렇다면 할당 시 배열 변수가 설정된 것으로 간주되지 않는 이유는 무엇입니까 ()?

$ ar=()
$ echo ${ar-This is a new value}
This is a new value

감사해요.

답변1

In은 bashin과 동일합니다 ksh. 여기서 $var는 배열 $var이며 실제로는 의 약어입니다 ${var[0]}.

그래서:

var=([1]=whatever [2]=blah)

${var+set}로 확장되지 않고 set, 인덱스 0을 가진 요소가 없기 [[ -v var ]]때문에 false를 반환합니다 . ).$varbashksh

bash(적어도 4.3 이후) 에서는 다음을 사용하여 변수를 배열로 선언할 때:

typeset -a var

var처음에는 설정되지 않았습니다. 빈 목록으로 설정되지도 않았습니다. 에서는 오류 4.3typeset -p var반환됩니다. 버전 4.2 이하에서는 다음을 출력합니다.

declare -a a='()'

(배열을 선언하면 빈 목록이 할당되는 것과 같습니다 zsh.)

4.4에서 출력은 다음과 같습니다.

declare -a var

따라서 4.3부터 설정되지 않은(그러나 선언된) 배열은 빈 목록이 할당된 배열과 동일하지 않습니다.

그러나 프로그래밍 방식으로 두 가지의 차이점을 구분하는 것은 어렵습니다. 그러나 실제로 이러한 구별은 그다지 유용하지 않습니다. 아마도 배열에 몇 개의 요소가 있는지 알고 싶을 것입니다.

((${#array[@]})) || echo array has no element

더 나은 배열 설계를 갖춘 쉘은 zsh, rcfish를 참조하십시오 .yash

답변2

설정되지 않은 경우 구문은 ${var-foo}다음으로 확장됩니다.foovar또는 비어 있음. 빈 배열이 바로 그것입니다.

당신이 인용한 대로:

아래 첨자가 할당된 경우 배열 변수는 설정된 것으로 간주됩니다.

귀하 사이트의 예( )에서는 ar=()아래 첨자에 값을 할당하지 않습니다.

답변3

전체 배열을 테스트하는 올바른 방법은 다음과 같습니다.

[[ ${ar[@]+set} == set ]] && echo "array has a value may be a null"

인덱스 0의 값에 대한 테스트를 작성 중입니다. 이 두 가지는 동일합니다.

${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의 모든 구성원으로 확장됩니다.

관련 정보