空 Bash 索引数组的初始化

问题描述 投票:0回答:1

我已经阅读了一些有关该主题的相关问题,但没有找到我想要的确切问题。我希望不是因为它太愚蠢了。

在 Bash 5(5.2.15,如果重要的话)中,声明一个数组有什么区别吗:

declare -a foo

相比:

declare -a foo=()

我想知道第一个声明是否确实确保创建空数组,还是只有第二个声明才能保证这一点?

你可能会问,初始化一个空数组有什么意义呢?为什么不只在需要存储第一个元素时才初始化它?

嗯,我不知道,也许吧?

那么另一个问题出现了,只有在使用追加运算符存储第一个元素时才初始化数组是否安全?喜欢:

bar+=('baz')

bar在附加第一个元素之前未定义)

即使设置了选项名词集,这似乎也不是问题,但是这样做,我是否确信“baz”将始终是数组中的第一个元素?这样做安全吗?

另外,在我需要更改变量的默认范围的情况下,我想我无法避免使用

declare
(或
local
),并且每次附加时调用declare 或 local 似乎是错误的一个元素(虽然它似乎有效)。

抱歉,如果这是一个愚蠢的问题或措辞不好。

祝你有美好的一天。

arrays bash initialization
1个回答
0
投票

解决

declare -a foo
declare -a foo=()
(与
foo=()
)问题...

结果将取决于

foo
之前的
declare -a
中的内容。

$ foo=a                                       # set to single character
$ declare -p foo
declare -- foo="a"

$ declare -a foo                              # convert to array
$ declare -p foo
declare -a foo=([0]="a")                      # maintains initial value of 'a'


---------------------------------

$ foo=a                                       # set to single character
$ declare -p foo
declare -- foo="a"

$ declare -a foo=()                           # convert to array but also clear contents
$ declare -p foo
declare -a foo=()                             # array is empty


---------------------------------

$ foo=(a b c)                                 # set to 3 element array
$ declare -p foo
declare -a foo=([0]="a" [1]="b" [2]="c")

$ declare -a foo                              # (re)declare as array
$ declare -p foo
declare -a foo=([0]="a" [1]="b" [2]="c")      # maintains intitial set of 3 values


---------------------------------

$ foo=(a b c)                                 # set to 3 element array
$ declare -p foo
declare -a foo=([0]="a" [1]="b" [2]="c")

$ declare -a foo=()                           # (re)declare as array but also clear contents
$ declare -p foo
declare -a foo=()                             # array is empty

调查结果:

  • 如果
    foo
    未定义,则
    declare -a foo
    declare -a foo=()
    foo=()
    的行为相同
  • 如果
    foo
    已预定义,则
    declare -a foo
    将保持预定义值,而
    declare -a foo=()
    foo=()
    将清除
    foo
  • 的内容

如果您 100% 确定您的变量(在本例中为

foo
)未定义,那么使用
declare -a foo
declare -a foo=()
foo=()
是安全的。

如果您不确定变量的内容(例如,它是由父进程导出的),那么使用

declare -a foo=()
foo=()
显式清除变量会更安全。

注意: 如果您最初定义

foo
,然后尝试定义为关联数组 (
declare -A foo
),这些测试用例的结果将会有所不同。

如果您需要数组为空,那么我建议始终显式地通过

declare -a foo=()
foo=()
将数组定义为空。

© www.soinside.com 2019 - 2024. All rights reserved.