HappyFace Asked: 2019-08-12 22:49:57 +0800 CST2019-08-12 22:49:57 +0800 CST 2019-08-12 22:49:57 +0800 CST 在 zsh 函数中返回数组的惯用方式是什么? 772 我有这个功能, rpargs () { local i args=() for i in "$@" do test -e "$i" && args+="$(realpath --canonicalize-existing -- "$i")" || args+="$i" done } 我想回来args。我能想到的唯一方法是printf '%s\0'通过扩展标志然后拆分它(0@),或者使用像上面的代码一样的全局。 zsh array 2 个回答 Voted Best Answer Stéphane Chazelas 2019-08-13T00:50:04+08:002019-08-13T00:50:04+08:00 zsh的return内置函数只能像_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除了引用/取消引用之外,它还意味着分叉一个进程并通过管道传输输出。 psprint 2019-08-29T17:12:37+08:002019-08-29T17:12:37+08:00 惯用的方法是只使用reply数组。如果需要,您可以使用该(P)标志并返回一个名称传递给函数的数组: myfunc() { local arrayname=${1:-reply}; shift # ... : ${(PA)arrayname::="${args[@]}"} }
zsh
的return
内置函数只能像_exit()
系统调用一样返回一个 32 位有符号整数。虽然这比大多数其他类似 Bourne 的 shell 更好,但它仍然不能返回任意字符串或字符串列表,如rc
/es
shell。返回状态更多的是关于返回成功/失败指示。在这里,或者,您可以让函数将要填充的数组的名称作为参数,例如:
您的
printf '%s\0'
方法不适用于包含 NUL 的数组元素。相反,您可以使用
qq
参数扩展标志在输出上引用元素,在输入上使用z
(解析引号)和Q
(删除引号),例如:但除了不那么易读之外,它的效率也较低,因为这意味着
myfunc
除了引用/取消引用之外,它还意味着分叉一个进程并通过管道传输输出。惯用的方法是只使用
reply
数组。如果需要,您可以使用该(P)
标志并返回一个名称传递给函数的数组: