我想创建一个包含两个数字的数组的数组。非常直截了当。但是,如果我在第一个数组之前没有提供前导逗号,则它是不正确的。为什么需要这个领先的逗号?
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
答案 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 PowerShell 和 Understanding 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)
最后一步是要了解
由PowerShell Team Blog解释的本质上,
@(...)
操作是[array] $(...)
(链接由Christopher G. Lewis answer给出)。尽管从本质上讲 的含义和局限性对我来说并不完全清楚。