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

lit*_*lit 8 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
Run Code Online (Sandbox Code Playgroud)

Ans*_*ers 11

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

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

并有一个阵列出来.

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

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

基本上,你的表达是相同的

$files1 = @(
4
1024
, @(7, 16)
)
Run Code Online (Sandbox Code Playgroud)

要么

$files1 = 4, 1024, @(7, 16)
Run Code Online (Sandbox Code Playgroud)

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

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

$files1 = @(4, 1024),
          @(7, 16)
Run Code Online (Sandbox Code Playgroud)

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

$files1 = (4, 1024),
          (7, 16)
Run Code Online (Sandbox Code Playgroud)

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

欲了解更多信息,请参阅about_Operators.

  • 好的答案,但我建议不要(也)将`@(...)`称为_array构造运算符_;如果要使用其他名称调用,则将其称为_array guarantor operator_; 简而言之,如果某事物还不是数组,则使其成为一个数组。为了使`@(...)`成为创建数组_literals_所需的_never_,我建议从最后的代码片段中删除`@`:$ files1 =(4,1024),(7,16) `。 (2认同)

Mic*_*ann 5

理解数组子表达式运算符的@( )关键是认识到您不需要它来创建数组,而是使用逗号运算符创建数组,

作为二元运算符,逗号创建一个数组。作为一元运算符,逗号创建一个只有一个成员的数组。将逗号放在成员前面。

$myArray = 1,2,3
$SingleArray = ,1
Run Code Online (Sandbox Code Playgroud)
$xs = (1,2,3), (4,5,6)       # Count: 2    
$ys = (1,2,3),
(4,5,6)                      # Count: 2
Run Code Online (Sandbox Code Playgroud)

现在考虑

# 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)
Run Code Online (Sandbox Code Playgroud)

最后一步是要意识到

本质上,该@(...)操作是语法糖 [array] $(...)

正如PowerShell 团队博客所解释的(该链接由Christopher G. Lewis 回答提供)。虽然本质上的含义和局限性我并不完全清楚。