我在 mac OS Ventura 上使用 zsh 5.8.1,我正在尝试这个:
#!/bin/zsh
typeset -A foo=(
[apple]="red"
[banana]="yellow"
)
echo $foo[apple] # Ok! prints "red"
function foobar () {
echo $1 # logs "foo"
local -A bar=$1 # Error! inconsistent type for assignment
echo $bar[apple]
}
foobar foo
但是我收到这个错误:
foobar:local:2: bar: 赋值类型不一致
我尝试了一些没有成功的事情:
foobar foo
改为foobar $foo
,同样的错误local -A bar=$1
改为declare -A bar=$1
,同样的错误我能做什么?
需要使用间接参数展开。因为
bar
包含名字foo
,所以${(P)bar}
等价于$foo
。这意味着您可以用与 ${(P)bar}
相同的方式对 $foo
进行索引。
% print ${${(P)bar}[apple]}
red
按照建议,我深入研究了 zsh 参数扩展 (
man zshexpn
),这对我有用:
#!/bin/zsh
typeset -A foo=(
[apple]="red"
[banana]="yellow"
)
function foobar () {
# Expand the contents of 1 into a new associative array
typeset -A bar=(${(@Pkv)1})
# Add new item
bar[berry]="purple"
for key value in ${(@kv)bar}; do
# Print all 3 fruits and its colors
echo "$key=$value"
done
# Replace global foo
eval "typeset -gA $1=(${(@kv)bar})"
}
foobar foo
echo $foo[berry] # purple
关键是
${(@Pkv)1}
这似乎将参数 1
的内容扩展到 new 关联数组中。可以使用 t
扩展 ${(t)var}
: 确认类型
echo ${(t)${(@Pkv)1}} # association
这个新的关联数组可以分配给一个变量:
typeset -A bar=(${(@Pkv)1})
如果这个新关联被更改并且需要保留这些更改覆盖原始变量:
eval "typeset -gA $1=(${(@kv)bar})"
我现在不太了解 zsh 或 zsh 最佳实践,所以欢迎提出建议! 🍪