如何使用 zsh 将关联数组定义为函数参数?

问题描述 投票:0回答:2

我在 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
    ,同样的错误

我能做什么?

arrays zsh associative-array
2个回答
0
投票

需要使用间接参数展开。因为

bar
包含名字
foo
,所以
${(P)bar}
等价于
$foo
。这意味着您可以用与
${(P)bar}
相同的方式对
$foo
进行索引。

% print ${${(P)bar}[apple]}
red

0
投票

按照建议,我深入研究了 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 最佳实践,所以欢迎提出建议! 🍪

© www.soinside.com 2019 - 2024. All rights reserved.