【问题标题】:Explaining local -a 'xkeys=("${!'"$1"'[@]}")'解释本地 -a 'xkeys=("${!'"$1"'[@]}")'
【发布时间】:2014-07-24 13:48:12
【问题描述】:

此代码作为bash-hackers.org wiki page 的数组间接解决方法提供,作为间接获取数组长度和索引的示例。

这个Stackoverflow question也提到了。

我想具体了解为什么local -a 'xkeys=("${!'"$1"'[@]}")' 有效。这里发生了什么。我知道等号右边有三个不同的字符串:

  1. 'xkeys=("${!'
  2. “$1”
  3. '[@]}")'

为什么会这样?

这是代码:

isSubset() {
local -a 'xkeys=("${!'"$1"'[@]}")' 'ykeys=("${!'"$2"'[@]}")'
set -- "${@/%/[key]}"

(( ${#xkeys[@]} <= ${#ykeys[@]} )) || return 1

local key
for key in "${xkeys[@]}"; do
    [[ ${!2+_} && ${!1} == ${!2} ]] || return 1
done
}

谢谢

【问题讨论】:

  • 我只是解释了一堆isSubsethere的操作,虽然没有具体说明这一点。

标签: arrays bash indirection


【解决方案1】:

@tripleee 基本上是正确的,尽管遗漏了一个细节(几分钟前我在回答 here 时写下我对 isSubset 其余部分的解释时也犯了同样的错误)。

这里的关键细节是local(以及declaretypeset)自己解析他们的参数。

让我们来看看这条线的各种扩展

local -a 'xkeys=("${!'"$1"'[@]}")' 'ykeys=("${!'"$2"'[@]}")'

现在拆分引用的部分将有助于理解。这让我们明白了

local -a 'xkeys=("${!' "$1" '[@]}")' 'ykeys=("${!' "$2" '[@]}")'

扩展为

local -a 'xkeys=("${!' "a" '[@]}")' 'ykeys=("${!' "b" '[@]}")'

重新组装成

local -a 'xkeys=("${!'"a"'[@]}")' 'ykeys=("${!'"a"'[@]}")'

结合相邻的引用词得到我们

local -a 'xkeys=("${!a[@]}")' 'ykeys=("${!a[@]}")'

如果这不是local,我们将在这一点上完成(也可以eval)。

例如echo: e() { echo 'xkeys=("${!'"$1"'[@]}")' 'ykeys=("${!'"$2"'[@]}")'; }; e a b 输出xkeys=("${!a[@]}") ykeys=("${!b[@]}")

但是因为这是local,正如我之前所说,它自己解析(事实上你知道它已经解析了,因为否则分配给a{0..5} 扩展将不起作用。尝试echo {0..5} vs. "{0..5}" 看看我的意思)单引号字符串由local 重新评估,并发生数组索引扩展。所以${!a[@]} 扩展为a 的索引,${!b[@]} 扩展为b 的索引。

【讨论】:

    【解决方案2】:

    ${!"$1"} 获取在$1 中命名的变量。 ${variable[@]} 扩展到数组 variable 中的所有元素。所以这基本上将$1命名的数组复制到xkeys中。

    【讨论】:

    • 我明白这是应该的。我想问题是为什么它会以这种特定方式工作,但当我将它作为一个字符串(即删除单引号)时却不是。有关更多上下文,您可以查看我的一些探索here
    • ! 不是作为$1 扩展的一部分被吞没,它是数组索引扩展(与数组值扩展相反)。 ! 在这个位置上的重载性质是复杂和令人困惑的。
    猜你喜欢
    • 2012-10-15
    • 1970-01-01
    • 2011-10-21
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 2013-12-25
    相关资源
    最近更新 更多