`declare -a A` cria um array vazio `A` no Bash?

`declare -a A` cria um array vazio `A` no Bash?

Cria declare -a Aum array vazio Ano bash ou apenas define um atributo caso Aseja atribuído posteriormente?

Considere este código:

set -u
declare -a A
echo ${#A[*]}
echo ${A[*]}
A=()
echo ${#A[*]}
echo ${A[*]}
A=(1 2)
echo ${#A[*]}
echo ${A[*]}

Qual deve ser o resultado esperado?

No Bash 4.3.48(1) recebo bash: A: unbound variableao consultar o número de elementos após declare. Também recebo esse erro ao acessar todos os elementos. Eu sei que as versões posteriores do Bash tratam isso de maneira diferente. Ainda assim, gostaria de saber se declarerealmentedefineuma variável (para estar vazia).

Responder1

Isso depende se a variável correspondente já foi declarada no escopo atual (nível superior, também conhecido como função global ou atual) antes.

Se não tiver sido declarada no escopo atual (e cuidado, pois no escopo de nível superior, a variável pode terdeclarado(e atribuído) importando-o do ambiente), então ele o declara (torna-o local para a função quando no escopo da função), atribuindo-lhe um tipo, mas não o inicializa, nem mesmo para uma lista vazia ( declare -p ashows declare -a a, não declare -a a=()como seria se você tivesse declarado e/ou atribuído a=()).

Se já tivesse sido declarado no escopo atual (por exemplo, porque foi importado como uma variável escalar do ambiente quando estava no escopo global), então declare -a atentariaconverterpara uma matriz.

Se anteriormente era um escalar, então se torna um ([0]=value-of-the-variable)array. Se já era um array, ele permanece intacto. Se fosse uma matriz associativa, falharia com um cannot convert associative to indexed arrayerro.

Observe que isso declare anão converteria um array ou hash em escalar. bashnão seria capaz de converter um hash/array em escalar de qualquer maneira. Você pode usar declare +aA apara forçar um escalar (que falharia com um erro se a variável fosse anteriormente um hash/matriz no escopo atual).

No seu caso, a variável provavelmente ainda não foi declarada no escopo atual, então acabou declarada, mas não atribuída, o que explica por que a tentativa de expandi-la falhou em set -u.

Essa distinção entre doisdeclaradoeatribuído/definirestados de uma variável não são específicos para bash. No POSIX sh, você também pode exportcriar uma variável ou criá-la readonlysem fornecer um valor.

$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set

Observe que unsetambos cancelam a definição e declaram a variável. In bashe mkshpode yashrestaurar a variável de um escopo externo.

Em zsh, exceto na shemulação, o uso typesetde uma variável declara e define-a com um valor vazio se ainda não estiver definido ou tiver sido definido, mas de um tipo diferente (escalar vs array vs array associativo).

informação relacionada