如何将数组传递到函数中,并且数组的更新会反映到函数外部

如何将数组传递到函数中,并且数组的更新会反映到函数外部

我试图将一个数组传递到一个函数中,对数组所做的任何更改都会反映在函数之外

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用于其他黑客攻击。

相关内容