为什么创建数组时需要使用前导逗号?

时间:2017-03-13 19:40:07

标签: arrays powershell

我想创建一个包含两个数字的数组的数组。非常直截了当。但是,如果我在第一个数组之前没有提供前导逗号,则它是不正确的。为什么需要这个领先的逗号?

PS C:\src\powershell> Get-Content .\fr-btest.ps1
$files1 = @(
@(4, 1024)
, @((7), (16))
)

$files1
$files1.GetType()
$files1.Length
$files1.Count
'========'

$files2 = @(
, @(4, 1024)
, @((7), (16))
)

$files2
$files2.GetType()
$files2.Length
$files2.Count

PS C:\src\powershell> .\fr-btest.ps1
4
1024
7
16

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
3
3
========
4
1024
7
16
True     True     Object[]                                 System.Array
2
2

3 个答案:

答案 0 :(得分:10)

@()array subexpression operator,其工作方式与您可能习惯使用其他语言的数组构造运算符不同。运算符计算嵌套的子表达式,并将该表达式的输出作为数组返回。意思是你可以做这样的事情:

@(
Write-Output 'foo'
Get-Content 'C:\some\file.txt'
Test-Connection '192.168.23.42' -Count 1
)

并有一个阵列出来。

对于您的第一个示例,这意味着单独计算两个语句@(4, 1024), @((7), (16)),然后将这两个语句的集合输出作为数组返回。

第一个语句(@(4, 1024))输出两个整数,但第二个语句(, @((7), (16)))输出两个整数的数组。这是因为该语句中的前导逗号被解释为一元数组构造运算符(或逗号运算符),因此您将获得一个嵌套在另一个数组中的数组,并且在输出期间只展开外部数组。

基本上,你的表达与

相同
$files1 = @(
4
1024
, @(7, 16)
)

$files1 = 4, 1024, @(7, 16)

你的第二个例子避免了这个陷阱,因为两个嵌套数组都附加了一元数组构造运算符,因此不会被完全展开。

话虽如此,我建议以更清晰的方式定义数组,例如:像这样:

$files1 = @(4, 1024),
          @(7, 16)

或(使用分组表达式而不是数组子表达式),如下所示:

$files1 = (4, 1024),
          (7, 16)

避免像你观察到的那样的惊喜。在此处定义数组不需要外部@()。 PowerShell通过第一行末尾的尾随逗号自动检测到它。

有关详细信息,请参阅about_Operators

答案 1 :(得分:3)

Powershell使用逗号和换行符作为数组分隔符。你的第一次声明:

$files1 = @(
@(4, 1024)
, @((7), (16))
)

创建以下内容:

$files1[0] = 4
$files1[1] = 1024
$files1[2] = @(7,16)

你的第二次声明

$files1 = @(
, @(4, 1024)
, @((7), (16))
)

创建以下内容:

$files1[0] = @(4, 1024)
$files1[1] = @(7, 16)

关于解析决策,它取决于行上遇到的第一个非空白字符: Array Literals In PowerShellUnderstanding PowerShell Parsing Modes

答案 2 :(得分:3)

了解Array subexpression operator @( )的关键是认识到您不需要它来创建数组,而是使用Comma operator ,创建数组。

  

作为二进制运算符,逗号创建一个数组。作为一元运算符,   逗号创建一个包含一个成员的数组。将逗号放在成员之前。

$myArray = 1,2,3
$SingleArray = ,1
$xs = (1,2,3), (4,5,6)       # Count: 2    
$ys = (1,2,3),
(4,5,6)                      # Count: 2

现在考虑

# A - two expressions, each expression yields one array of size 3
(1,2,3)
(4,5,6)

# B - one expression resulting in an array of two elements
(1,2,3),
(4,5,6)

# C - similar to A except the sizes are 3 and 1 
#     (the second array contains a single element)
(1,2,3)
,(4,5,6)

最后一步是要了解

  

本质上,@(...)操作是   [array] $(...)

PowerShell Team Blog解释的

(链接由Christopher G. Lewis answer给出)。尽管从本质上讲 的含义和局限性对我来说并不完全清楚。