在 zsh 函数中返回数组的惯用方法是什么?

在 zsh 函数中返回数组的惯用方法是什么?

我有这个功能,

rpargs () {
    local i
    args=()
    for i in "$@"
    do
        test -e "$i" && args+="$(realpath --canonicalize-existing -- "$i")"  || args+="$i"
    done
}

我想回来args。我能想到的唯一方法是要么printf '%s\0'通过扩展标志拆分它(0@),要么使用像上面的代码这样的全局变量。

答案1

zshreturn内置函数只能像_exit()系统调用一样返回 32 位有符号整数。虽然这比大多数其他类似 Bourne 的 shell 更好,但它仍然无法像rc/ esshell 那样返回任意字符串或字符串列表。返回状态更多的是返回成功/失败指示。

或者,您可以让函数将要填充的数组名称作为参数,例如:

myfunc() {
  local arrayname=$1; shift
  # ...
  eval $arrayname'=("$elements[@]")'
  # the returned $? will be 0 here for success unless that eval command
  # fails.
}

myfunc myarray other args

您的printf '%s\0'方法不适用于包含 NUL 的数组元素。

相反,您可以使用qq参数扩展标志在输出上引用元素,并在输入上z使用(解析引号)和Q(删除引用),例如:

myfunc() {
   # ...
   print -r -- ${(qq)elements}
}

myarray=("${(@Q)${(z)$(myfunc)}}")

myfunc但除了不太易读之外,它的效率也较低,因为除了引用/取消引用之外,它还意味着分叉进程并通过管道传输输出。

答案2

惯用的方法是仅使用数组reply。如果需要,您可以使用该(P)标志并返回一个数组,该数组的名称将传递给函数:

myfunc() {
  local arrayname=${1:-reply}; shift
  # ...
  : ${(PA)arrayname::="${args[@]}"}
}

相关内容