`declare -a A` 是否在 Bash 中创建一个空数组 `A`?

`declare -a A` 是否在 Bash 中创建一个空数组 `A`?

是否在 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取消设置和取消声明变量。在 中bashmkshyash可以从外部范围恢复变量。

在 中zsh,除模拟外,如果变量尚未设置或已设置但来自不同类型(标量、数组或关联数组),则shusing on 变量会声明并将其设置为空值。typeset

相关内容