Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
910 views
in Technique[技术] by (71.8m points)

powershell - Why is a leading comma required when creating an array?

I want to create an array containing arrays of two numbers. Pretty straightforward. However, If I do not provide a leading comma before the first array, it is incorrect. Why is this leading comma required?

PS C:srcpowershell> 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:srcpowershell> .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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

@() is the array subexpression operator, which works differently than array construction operators you may be used to from other languages. The operator evaluates the nested subexpression and returns the output of that expression as an array. Meaning you can do something like this:

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

and have an array come out.

For your first example this means that the two statements @(4, 1024) and , @((7), (16)) are evaluated individually, and the collective output of the two statements is then returned as an array.

The first statement (@(4, 1024)) outputs two integers, but the second statement (, @((7), (16))) outputs an array of two integers. That is because the leading comma in that statement is interpreted as the unary array construction operator (or comma operator), so you get an array nested in another array, and only the outer array is unrolled during output.

Essentially, your expression is the same as

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

or

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

Your second example avoids this pitfall, because both nested arrays are prepended with the unary array construction operator and thus protected from being completely unrolled.

With that said, I would recommend to define arrays in a more clear-cut way, e.g. like this:

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

or (using grouping expressions instead of array subexpressions) like this:

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

to avoid surprises like the one you observed. The outer @() isn't necessary for defining an array here. PowerShell automatically detects that via the trailing comma at the end of the first line.

For further information see about_Operators.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...