Zsh 使用Oa标志对参数扩展结果使用标量或数组赋值时的顺序不同

Zsh 使用Oa标志对参数扩展结果使用标量或数组赋值时的顺序不同,zsh,parameter-expansion,Zsh,Parameter Expansion,在zsh中,如果我执行以下操作 x=(1233) y=${(Oa)x} z=(${(Oa)x}) 然后echo$y将输出1 2 3,但echo$z将输出3 2 1 显然,y是一个标量,z是一个数组,但为什么对y的标量赋值不最终为它赋值“3 2 1”?似乎是因为替换规则,'10。“强制连接”优先于“19”。“订购” 以下是zsh文档: 规则 以下是替换规则的摘要… … 10强制连接 如果存在(j)标志,或不存在(j)标志,但字符串将按照规则11进行拆分,并且在规则5中未进行连接,则使用给定字符串

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

x=(1233)
y=${(Oa)x}
z=(${(Oa)x})
然后
echo$y
将输出
1 2 3
,但
echo$z
将输出
3 2 1


显然,y是一个标量,z是一个数组,但为什么对y的标量赋值不最终为它赋值“3 2 1”?

似乎是因为替换规则,'10。“强制连接”优先于“19”。“订购”

以下是zsh文档:

规则
以下是替换规则的摘要…

10强制连接
如果存在
(j)
标志,或不存在
(j)
标志,但字符串将按照规则11进行拆分,并且在规则5中未进行连接,则使用给定字符串或$IFS的第一个字符(如果没有)将值中的任何单词连接在一起。请注意,
(F)
标志隐式提供了一个字符串,用于以这种方式进行连接。

19订购
如果结果仍然是一个数组,并且出现了
(o)
(o)
标志之一,则该数组将重新排序

---


y=${(Oa)x}
vs
z=(${(Oa)x})

第一种形式是标量赋值,第二种形式是赋值数组值

说明

标量参数的值也可以通过写入来指定:
name=value

---

若要指定数组值,请写入以下内容之一:
设置-名称值…

name=(值…)

name=([key]=value…)

---

因此,第一种形式产生标量值,第二种形式产生数组值:
echo
以详细形式显示带有的值。)

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

---


这符合规则10。如果表格中没有双引号。

谢谢。我不太明白为什么标量赋值会发生这种情况,而数组赋值不会。你能不能进一步解释一下,为什么在一种情况下会发生强制连接,而在另一种情况下不会发生?作为标量赋值,它是否以某种方式隐式地设置了一些不同的标志?与
man zshparam
不同,“在标量赋值中,值被扩展为单个字符串,其中数组的元素被连接在一起;[…]”。我认为这是第5条的一部分,虽然没有这样说。就规则19而言,
x
的扩展在标量赋值中不再是数组,而是在数组赋值中。换句话说,扩展的上下文决定是否忽略
(Oa)
。非常感谢@chepner。我不确定这是否是规则5。但我真的(错了?)读到了规则10,因为表格中没有双引号,我也不清楚。我的解释是,因为标量赋值的右侧行为类似于双引号,所以当您到达规则10时,数组元素已经被连接,就像规则5已经完成连接一样。但是无论哪种方式,当规则19检查是否存在可以应用
(Oa)
的数组值时,这两条规则中的一条已经将数组元素合并为单个字符串。
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