取消设置数组中的最后剩余元素

时间:2015-05-19 09:32:43

标签: ksh

我正在使用ksh93中的数组实现各种数据结构(例如堆栈),并且希望避免跟踪索引和计数器,以保持简单。我使用array+=(element)进行推送,使用print ${array[-1]}执行 pop ,然后使用unset array[-1]

这通常有效,除非在弹出堆栈上的最后一个剩余元素(array[0])之后:当我在此之后推送一个项目时,它被分配到索引1,而不是0.例如,如果我运行以下带有PS4='> ' ksh -x的脚本:

    typeset -a foo
    foo+=(a b c)
    print -C foo
    unset foo[-1]
    foo+=(d)
    print -C foo
    unset foo[-1]; unset foo[-1]; unset foo[-1]
    print -C foo
    print ${#foo[@]}
    foo+=(e)
    print -C foo

我得到以下输出:

    > typeset -a foo
    > foo+=( a b c )
    > print -C foo
    (a b c)
    > unset 'foo[-1]'
    > foo+=( d )
    > print -C foo
    (a b d)
    > unset 'foo[-1]'
    > unset 'foo[-1]'
    > unset 'foo[-1]'
    > print -C foo

    > print 0
    0
    > foo+=( e )
    > print -C foo
    ([1]=e)

除了最后一次追加操作外,一切都很好。即使数组被验证为空,但它的行为就像在索引0处有一个空元素一样。

我可以解决这个问题,例如不依赖索引0处的第一个项目,或者跟踪索引并执行明确的array[index]=element赋值,但我仍然想知道是否可以完全避免它。我也知道我可以做set -A array -- "${array[@]}" element(这可以按预期工作),但这并不像简单的+=操作那么优雅。我搜索了手册页,Bolsky& Korn书和Rosenblatt&罗宾斯在线预订,但未能在任何地方找到这种行为。

有人知道为什么会这样,和/或如何避免它?谢谢!

1 个答案:

答案 0 :(得分:0)

这不是一个解决方案,但它可能会有一些额外的调试步骤。

我总是使用typeset -p来获取变量的规范表示。如果您在运行上一个unset后进行尝试,则会看到foo声明仍然包含0索引,但没有为其分配值。 (这与分配给它的空字符串不同,它显示为''。然而,这与各种其他数组内省形式相矛盾,正如您在询问数组计数时所看到的那样。

坦率地说,我认为这可能是ksh中的一个错误,唯一的解决方案可能是将其报告给ast-users mailgroup

> typeset -a foo
> foo+=(a b c)
> print -C foo
(a b c)
> unset foo[-1]
> foo+=(d)
> print -C foo
(a b d)
> unset foo[-1]; unset foo[-1]; unset foo[-1]
> print -C foo

> print ${#foo[@]}
0
> typeset -p foo
typeset -a foo=([0]=)
> print ${!foo[@]}

> set -u
> print ${foo[0]}
./ksh: foo[0]: parameter not set
>