zsh中如何向函数传递数组 实现类似bash nameref的效果?
问题原因
zsh 对 nameref(名称引用)的实现和 bash 不兼容,bash 中用local -n定义名称引用的写法不被 zsh 的local命令识别,因此触发bad option: -n报错。
解决方案
方案1:使用zsh原生nameref语法(推荐,代码改动最小)
zsh 5.3及以上版本提供了专门的nameref关键字定义名称引用,直接替换原代码中的local -n即可正常运行,逻辑和原bash代码完全一致:
foo(){ nameref _array1=$1 nameref _array2=$2 echo ${_array1[@]}, ${_array2[@]} } main(){ local array1=(1 1 1 1) local array2=(2 2 2 2) foo array1 array2 } main
如果偏好和bash类似的typeset写法,也可以替换为typeset -n,效果完全相同:
foo(){ typeset -n _array1=$1 typeset -n _array2=$2 echo ${_array1[@]}, ${_array2[@]} }
方案2:数组元素直接传参(兼容低版本zsh/跨shell兼容)
如果使用的zsh版本低于5.3(无nameref支持),或者需要写出同时兼容bash、zsh的代码,可以通过传递数组长度+元素的方式,在函数内部切分恢复多个数组,不需要依赖名称引用特性:
foo(){ local len1=$1 local _array1=(${@:2:$len1}) local len2=${@[$((len1 + 2))]} local _array2=(${@:$((len1 + 3)):$len2}) echo ${_array1[@]}, ${_array2[@]} } main(){ local array1=(1 1 1 1) local array2=(2 2 2 2) # 传参顺序:数组1长度 -> 数组1所有元素 -> 数组2长度 -> 数组2所有元素 foo ${#array1[@]} ${array1[@]} ${#array2[@]} ${array2[@]} } main
注意:如果数组元素包含空格等特殊字符,方案2需要额外做转义处理,优先使用方案1的nameref写法。
内容的提问来源于stack exchange,提问作者Pogchamp_prob
相关产品推荐
相关产品推荐

