如何在zsh中将关联数组定义为函数参数?
解决zsh关联数组函数参数传递的类型不匹配问题
问题原因
你遇到的错误是因为zsh中无法直接通过变量名字符串或数组值展开来赋值给关联数组:
- 调用
foobar foo时,$1是字符串foo,直接赋值给local -A bar会因类型不匹配报错 - 改成
foobar $foo时,$foo展开的是关联数组的值列表(red yellow),缺少对应键信息,同样无法正确赋值给关联数组
两种可行解决方案
方案1:使用名称引用(Nameref)
zsh 5.3及以上版本支持名称引用,通过-n选项让变量成为另一个变量的引用,直接关联原数组:
#!/bin/zsh typeset -A foo=( [apple]="red" [banana]="yellow" ) echo $foo[apple] # 正常输出"red" function foobar () { echo $1 # 输出"foo" local -n bar=$1 # 创建名称引用,bar指向foo echo $bar[apple] # 输出"red" } foobar foo
方案2:复制关联数组的键值对
如果不需要引用原数组,而是想创建独立副本,可以使用间接展开结合数组展开符@:
#!/bin/zsh typeset -A foo=( [apple]="red" [banana]="yellow" ) echo $foo[apple] # 正常输出"red" function foobar () { echo $1 # 输出"foo" local -A bar=("${(@P)1}") # 间接展开$1对应的数组,复制键值对 echo $bar[apple] # 输出"red" } foobar foo
说明
local -n bar=$1:-n声明变量为名称引用,bar会直接指向$1对应的变量(即foo),修改bar会同步修改原数组"${(@P)1}":P表示间接引用(解析$1的值作为变量名),@表示展开数组的所有键值对(保留键值对应关系),以此完成关联数组的赋值
内容的提问来源于stack exchange,提问作者Adrian Guerrero
相关产品推荐
相关产品推荐

