我试图创建一个 bash“多维”数组,我看到了使用关联数组的想法,但我认为最简单的方法如下:
for i in 0 1 2
do
for j in 0 1 2
do
a[$i$j]="something"
done
done
设置和获取值很容易,但是如果 bash 为从索引 00 到 22 的元素顺序分配空间(我的意思是分配位置 {0,1,2,3, 4,...,21,22}),而不仅仅是实际设置的元素:{00,01,02,10,11,...,21,22}。
这让我想知道,当我们以索引“n”启动 bash 数组时会发生什么?它是否为索引 0 到 n 分配足够的空间,或者是否单独分配第 n 个元素类别?
答案1
bash 中的数组索引与 ksh 中的数组索引(复制了 bash 的数组设计)可以是任何算术表达式。
在 中a[$i$j]="something"
,$i
和$j
变量被扩展,因此i=0 j=1
,变成a[01]="something"
,01
作为算术表达式,在 bash 中表示八进制数 1。有了i=0 j=10
,那就a[010]="something"
和 一样了a[8]="something"
。你会得到a[110]="something"
和x=11 y=0
。x=1 y=10
现在应该很明显这不是您想要的。
相反,您可以像在 C 中那样处理二维数组(矩阵):
matrix_size=3
for (( i = 0; i < matrix_size; i++ )) {
for (( j = 0; j < matrix_size; j++ )) {
a[i * matrix_size + j]="something"
}
}
(for (( ...; ...; ...))
从 ksh93 复制的类似 C 的构造)。
或者切换到支持多维数组的 ksh93:
for (( i = 0; i < 3; i++ )) {
for (( j = 0; j < 3; j++ )) {
a[i][j]="something"
}
}
使用键只是字符串的关联数组也可以实现多维数组:
typeset -A a
for (( i = 0; i < 3; i++ )) {
for (( j = 0; j < 3; j++ )) {
a[$i,$j]="something"
}
}
根据报告,您在所有三个中得到的结果变量typeset -p
:
-
declare -a a=([0]="something" [1]="something" [2]="something" [3]="something" [4]="something" [5]="something" [6]="something" [7]="something" [8]="something")
-
typeset -a a=((something something something) (something something something) (something something something) )
-
declare -A a=([0,2]="something" [0,1]="something" [0,0]="something" [2,1]="something" [2,0]="something" [2,2]="something" [1,2]="something" [1,0]="something" [1,1]="something" )
现在回答主题中的问题,在 bash 中,就像在 ksh 中一样,普通数组是稀疏的,这意味着您可以a[n]
定义而不a[0]
被a[n-1]
定义,所以从这个意义上说,它们不像 C 或大多数其他语言的数组或贝壳。
最初在 ksh 中,数组索引限制为 4095,因此您最多可以拥有 64x64 大的矩阵,此后该限制已提高到 4,194,303。在 ksh93 中,我看到这样做a[4194303]=1
确实分配了超过 32MiB 的内存,我猜想保存 4194304 64 位指针和一些开销,而这似乎不会发生在bash
,其中数组索引可以高达 9223372036854775807 (至少在 GNU/Linux amd64 上) ),而不分配比存储实际设置的元素所需更多的内存。
在所有其他支持数组的 shell 中((t)csh、zsh、rc、es、fish...),数组索引从 1 而不是 0 开始,并且数组是普通的非稀疏数组,您不能在没有设置的情况下进行a[2]
设置a[1]
即使设置为空字符串。
与大多数编程语言一样,bash 中的关联数组被实现为哈希表,没有顺序或等级的概念(您会注意到typeset -p
上面以看似随机的顺序显示它们)。
有关不同 shell 中阵列设计的更多详细信息,请参阅这个答案到测试 shell 对数组的支持。