我需要在函数内部填充数组,将其作为参数传递而不使用全局变量(该函数将在此处和不同的数组中调用)。
我已经阅读了这个讨论bash how to pass array as an argument to a function,并使用了按名称传递的解决方案,ALMOST可以解决这个问题。
这是我的代码
#!/bin/bash
function fillArray {
arrayName=$1[@]
array=("${!arrayName}")
for i in 0 1 2 3
do
array+=("new item $i")
done
echo "Tot items in function: ${#array[@]}"
for item in "${array[@]}"
do
echo $item
done
echo
}
myArray=("my item 0" "my item 1")
fillArray myArray
echo "Tot items in main: ${#myArray[@]}"
for item in "${myArray[@]}"
do
echo $item
done
这是输出
Tot items in function: 6
my item 0
my item 1
new item 0
new item 1
new item 2
new item 3
Tot items in main: 2
my item 0
my item 1
因此,函数正确使用作为参数传递的数组(前两项是主声明中添加的项),并将新项追加到数组中。在函数调用之后,在main中,添加的项将丢失。
我错过了什么?可能是一些传递参考/传递复制的东西......
谢谢!
答案 0 :(得分:2)
为了将来参考,bash
4.3:
function fillArray {
declare -n arrayName=$1
for i in 0 1 2 3
do
arrayName+=("new item $i")
done
echo "Tot items in function: ${#arrayName[@]}"
for item in "${arrayName[@]}"
do
echo $item
done
echo
}
答案 1 :(得分:1)
您正在将函数添加到函数内部的数组变量中,但数组或任何其他变量不会在BASH中作为参考传递。因此,在函数内部对这些变量所做的任何更改都不会在函数外部可见。
作为解决方法,您可以使用此示例中的全局变量:
# initialize an array
myArray=("my item 0" "my item 1")
useArrayInFunc { myArray+=("my item 2")); }
useArrayInFunc
printf "%s\n" "${myArray[@]}"
my item 0
my item 1
my item 2
答案 2 :(得分:0)
您需要将本地var分配给全局变量:
function fillArray {
local arrayName=$1
local ref=$arrayName[@]
local array=("${!ref}")
local i item key
for i in 0 1 2 3
do
array+=("new item $i")
done
echo "Tot items in function: ${#array[@]}"
for item in "${array[@]}"
do
echo $item
done
echo
for key in "${!array[@]}"; do
declare -g ${arrayName}["$key"]="${array[$key]}"
done
}
答案 3 :(得分:0)
在answer中使用这种技术。修改后,你可以
addtoarray () { var="$1"; shift 1; eval "$var+=($(printf "'%s' " "$@"))"; }
arr=('my item 0' 'my item 1')
printf "%s\n" "${arr[@]}"
echo ====
addtoarray arr 'my new item 2' 'my new item 3'
printf "%s\n" "${arr[@]}"
打印
my item 0
my item 1
====
my item 0
my item 1
my new item 2
my new item 3
也适用于初始化数组
addtoarray secarr $(seq 5)
printf "%s\n" "${secarr[@]}"
打印:
1
2
3
4
5
分解函数 - 作为代码生成器
addtoarray () { var="$1"; shift 1; eval "$var+=($(printf "'%s' " "$@"))"; }
$1
中)存入$var
并将其从参数中移出val1
val2
somearrayname+=('elemnts1' 'element2' .... )
somearrayname
是我们作为第一个arg传递的变量名称printf "'%s '" "$@"
从arg-list addtoarray arr val1 "spaced val2"
,我们会生成下一个字符串 arr+=('val1' 'spaced val2' )
这是将成员添加到名为arr
的数组的正确结构 - 无论是否在争议之前,例如添加新元素到最后。 (如果它是空的,结束就是它的开始)
eval
执行以上生成的字符串 $arr
($ arr是全局变量,因此在函数中也是可见的)最后 - 残酷地偷走了@Chepner的答案;)使用他的技术addtoarray
si简单如下:
addtoarray () {
declare -n arrname=$1
shift 1;
arrname+=("$@")
}
如果你有bash 4.3,你应该接受@Chepner的答案 - 这是最好的。