我试图将一个数组传递到一个函数中,对数组所做的任何更改都会反映在函数之外
function update_array()
{
${1[0]}="abc" # trying to change zero-index array to "abc" ,
# bad substitution error
}
foo=(foo bar)
update_array foo[@]
for i in ${foo[@]}
do
echo "$i" # currently changes are not reflected outside the function
done
我的问题是
1)如何访问索引数组,例如:零索引数组,在函数中,它的语法是什么
2)我如何更改此索引数组,以便更改也能反映在函数之外
答案1
有几个问题,按逻辑顺序解决:
- 风格(讨厌的事)
使用你的
${...}
语句update_array()
,${..}
语法为使用一个变量,不要定义它。例子:
foo[0]=abc # assigns 'abc' to foo[0]
解决办法是将数组名称存储在变量中。
不工作:
$1[0]=abc
在职的:
declare -g "$1[0]=abc" # -g arg is for a global variable
传递参数
update_array()
应该传递变量名(foo
在本例中),而不是数组的内容。foo[@]
没什么特别的,它是一个完全正常的字符串(在 Bash 中)。变量扩展
${foo[@]}
应该用双引号引起来。
代码的工作版本如下:
update_array() {
declare -g "$1[0]=abc"
}
foo=(foo bar)
update_array foo
for i in "${foo[@]}"; do
echo "$i"
done
## Following line added by me for further clarification
declare -p foo
正确打印结果为:
abc
bar
declare -a foo='([0]="abc" [1]="bar")'
答案2
在 Bash 中可能不需要声明变量。1是的,你可以使用declare
/typeset
以便更好地控制您的 bash 变量。所以我认为您不必仅为了声明新数组而创建函数。
下面的脚本演示了数组的直接定义:
#!/bin/bash
function define_array_elements() {
# You can note the array elements being defined directly, without a prior
# definition of the variable.
for i in {1..10}; do
var_name[$i]="Field $i of the list"
done
}
define_array_elements > /dev/null
for i in {1..10}; do
echo "Field $i is: ${var_name[$i]}"
done
(借用自如何声明一个数组但不定义它?只需稍作修改即可。
答案3
简短的回答是:你不能。Bash 没有通过引用传递变量的方法,因此没有通用的方法来实现它;你只能使用(丑陋的)黑客手段,包括间接和/或 eval。
即将推出的 bash 4.3 将引入 nameref 变量,允许您通过引用传递变量,但即使是此功能也存在不足,因为您仍然存在名称冲突的风险。
# example of passing variables by reference in bash 4.3
update_array() {
declare -n array=$1
array[0]=abc
}
foo=( foo bar )
update_array foo
printf '<%s>\n' "${foo[@]}" # outputs <abc> and <bar>
在该示例中,如果数组被命名array
为 而不是foo
,则它会失败,因为declare -n array=array
是一个错误(declare: array: nameref variable self references not allowed
)。
看http://mywiki.wooledge.org/BashFAQ/006用于其他黑客攻击。