Создает ли `declare -a A` пустой массив `A` в Bash?

Создает ли `declare -a A` пустой массив `A` в Bash?

Создает ли bash declare -a Aпустой массив Aили просто устанавливает атрибут на случай, если Aон будет назначен позже?

Рассмотрим этот код:

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

Каков должен быть ожидаемый результат?

В Bash 4.3.48(1) я получаю bash: A: unbound variableпри запросе количества элементов после declare. Я также получаю эту ошибку при доступе ко всем элементам. Я знаю, что более поздние версии Bash обрабатывают это по-другому. Все же я хотел бы знать, на declareсамом ли делеопределяетпеременная (должна быть пустой).

решение1

Это зависит от того, была ли соответствующая переменная уже объявлена ​​в текущей области видимости (верхний уровень, то есть глобальная или текущая функция).

Если она не была объявлена ​​в текущей области видимости (и помните, что в области видимости верхнего уровня переменная может быть объявлена)заявил(и назначается) путем импорта его из среды), затем он объявляет его (делает его локальным по отношению к функции, когда он находится в области видимости функции), назначает ему тип, но не инициализирует его, даже для пустого списка ( declare -p aпоказывает declare -a a, а не declare -a a=()так, как если бы вы объявили и/или назначили его с помощью a=()).

Если он уже был объявлен в текущей области действия (например, потому что он был импортирован как скалярная переменная из среды, когда находился в глобальной области действия), то declare -a aбудет предпринята попыткаконвертироватьего в массив.

Если ранее это был скаляр, то он становится ([0]=value-of-the-variable)массивом. Если это уже был массив, то он остается нетронутым. Если это был ассоциативный массив, то он завершается ошибкой cannot convert associative to indexed array.

Обратите внимание, что declare aне преобразует массив или хэш в скаляр. bashв любом случае не сможет преобразовать хэш/массив в скаляр. Вы можете использовать declare +aA aдля принудительного скаляра (это приведет к ошибке, если переменная ранее была хешем/массивом в текущей области видимости).

В вашем случае переменная, вероятно, еще не была объявлена ​​в текущей области видимости, поэтому она была объявлена, но не назначена, что объясняет, почему попытка ее расширения в set -u.

Это различие между двумязаявилиназначенный/наборсостояния переменной не являются специфическими для bash. В POSIX shвы также можете exportпеременную или создать ее, readonlyне присваивая ей значения.

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

Обратите внимание, что unsetоба метода отменяют и отменяют объявление переменной. В bash, mkshи yashон может восстановить переменную из внешней области видимости.

В zsh, за исключением shэмуляции, использование typesetпеременной объявляет и устанавливает ее в пустое значение, если оно еще не было установлено или было установлено, но из другого типа (скалярный, массив или ассоциативный массив).

Связанный контент