4

在 zsh 中,如果我执行以下操作

x=(1 2 3)
y=${(Oa)x}
z=(${(Oa)x})

然后echo $y将输出1 2 3echo $z将输出3 2 1

显然 y 是一个标量,而 z 是一个数组,但是为什么对 y 的标量分配最终没有将“3 2 1”分配给它呢?

4

1 回答 1

2

似乎因为替换规则,'10. Force Joining ' 优先于 '19. 订购'。

这是 zsh 文档:

规则
这里是替换规则的摘要...
...
10.强制连接
如果 (j) 存在标志,或者不存在(j)标志但字符串将按照规则 11 的规定进行拆分,并且不采用连接放在规则 5. 处,值中的任何单词都使用给定的字符串或 $IFS 的第一个字符(如果没有)连接在一起。请注意,该(F)标志隐含地提供了一个用于以这种方式连接的字符串。
...
19.排序
如果结果仍然是一个数组并且存在(o)or(O)标志之一,则对数组进行重新排序。

--- zshparam(1), 规则, zsh 参数


y=${(Oa)x} 对比 z=(${(Oa)x})

第一种是标量赋值,后一种是数组赋值。

描述
...
标量参数的值也可以通过以下方式赋值:
name=value

--- zshparam(1), 描述, zsh 参数

...

要分配数组值,请编写以下之一:
set -A name value ...
name=(value ...)
name=([key]=value ...)

--- zshparam(1), 数组参数, zsh 参数

因此,第一种形式产生标量值和后一种数组值:(
带有echo参数扩展标志(q)的详细形式的值。)

x=(1 2 3)
y=${(Oa)x}
echo ${(qqq)y}  ;# look the `y` value in a verbose form with `(qqq)` 
#=> "1 2 3"     ;# forced joining and resulted scalar value
z=(${(Oa)x})
echo ${(qqq)z}
#=> "3" "2" "1" ;# resulted array value

在标量赋值中,值被扩展为单个字符串,其中数组的元素连接在一起

--- zshparam(1), 数组参数, zsh 参数

这符合规则 10。如果表单不在双引号中。

于 2019-11-01T06:57:24.217 回答