declare -a A
是在 bash 中创建一个空数组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
实际定义了一个变量(为空)。
这取决于之前是否已经在当前范围(顶级也称为全局或当前函数)中声明了相应的变量。
如果尚未在当前作用域中声明它(并注意在顶级作用域中,变量可能已通过从环境中导入它来声明(并分配)),那么它声明它(使其成为函数的本地变量当在函数范围内时),为其分配一个类型,但不初始化它,甚至不初始化为一个空列表(
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
. 在 POSIXsh
中,您也可以export
创建一个变量或readonly
不给它一个值。请注意,
unset
取消设置和取消声明变量。在bash
,mksh
它yash
可以从外部范围恢复变量。在
zsh
中,除了在sh
仿真中,typeset
如果变量尚未设置或已设置但来自不同类型(标量、数组和关联数组),则使用变量声明并将其设置为空值。