调用Bash函数后数组索引发生变更的原因咨询
为什么调用Bash函数后数组索引发生了变更?
这是因为你在函数内外处理数组的方式存在两个关键问题,直接导致原关联数组的索引信息完全丢失了:
1. 关联数组的输出只保留了值,未携带索引
你在函数里用declare -A slots声明了一个关联数组(支持自定义非连续索引的数组类型),但当你用echo ${slots[@]}输出时,只会打印数组的值列表,完全不会携带任何索引信息。而且Bash的关联数组本身是无序的,${slots[@]}输出值的顺序是不确定的(你例子里输出的是10 7 8 9,就是这种无序性的体现)。
2. 赋值时自动创建了普通索引数组
当你执行slots=($(getSlots))时,你是把函数输出的字符串列表赋值给了一个普通索引数组——因为你没有用declare -A重新声明这个外部的slots变量,Bash会默认把它当作普通数组处理。普通数组的索引是系统自动从0开始连续分配的,所以不管原来的关联数组索引是什么,新数组都会按值的输入顺序依次分配0、1、2、3这些索引,这就是你看到输出索引变更的核心原因。
如何保留关联数组的索引和值?
如果想要完整保留关联数组的索引和值,不要用echo输出值列表,而是用declare -p输出数组的完整定义,然后在函数外通过eval解析这个定义。修改后的代码如下:
#!/bin/bash function getSlots { declare -A slots for index in `seq 7 10`; do slots[$index]=$index done declare -p slots # 输出关联数组的完整声明信息 } eval "$(getSlots)" # 解析并恢复关联数组的结构 for i in ${!slots[@]}; do echo "$i ${slots[$i]}" done
运行这段代码,你就能看到原来的索引(7、8、9、10)被完整保留下来了(不过输出顺序依然是无序的,这是关联数组的固有特性)。
内容的提问来源于stack exchange,提问作者Paulo Henrique Peres
相关产品推荐
相关产品推荐

