代码之家  ›  专栏  ›  技术社区  ›  Bax

为什么新行在PowerShell多维数组创建中改变了语义?[复制]

  •  0
  • Bax  · 技术社区  · 6 年前

    我想创建一个包含两个数字数组的数组。很直接。但是,如果我没有在第一个数组之前提供前导逗号,这是不正确的。为什么需要这个前导逗号?

    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 回复  |  直到 8 年前
        1
  •  12
  •   Ansgar Wiechers    6 年前

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

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

    让一个阵列出来。

    对于第一个示例,这意味着这两个语句 @(4, 1024) , @((7), (16)) 然后作为两个集合语句的输出单独求值。

    第一个陈述( )输出两个整数,但第二个语句( ,@((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 .

        2
  •  4
  •   Micha Wiedenmann Lieven Keersmaekers    6 年前

    了解 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 ). 尽管 本质上

        3
  •  3
  •   mklement0    6 年前

    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

    推荐文章