zsh 中 declare/typeset 与 "options" 数组的奇怪行为

Strange behaviour of declare/typeset with "options" array in zsh

我试图在 zsh 的脚本中声明一个名为 options 的变量。原来这是一些保留名称,zsh 在其下存储了一个关联数组。

function mcve() {
    options='';
}

$ mcve
mcve:1: options: attempt to set slice of associative array

试图用 declare 查看它的内容,但遇到了一个奇怪的行为。首次出现上述错误前后输出不同。

$ zsh
$ declare options
options

$ zsh
$ mcve
mcve:1: options: attempt to set slice of associative array
$ declare options
options=(autolist on printexitvalue off...<20 more lines>)

这是怎么回事?为什么输出不同? options 数组是否在第一次尝试使用它时声明?

我听说 typeset should be used 而不是 declare,但我的 man zshbuiltins 说它们完全相等。

另外,这个运行没有失败:

function mcve() {
declare options;
options='';
echo ok;
}

$ zsh
$ mcve
ok

为什么不同?

options 关联数组记录在 man zshmodules 下的 ZSH/PARAMETERS 中。我无法解释 declare options 的行为,但我会注意到 print $options[@] 会输出一个 on/off 值的列表,即使 declare options 什么都不显示。

在你的最后一个例子中,declare options 在函数定义中总是声明一个新的局部变量,无论是否已经存在同名的全局变量。