【问题标题】:How to pass array into anonymous function?如何将数组传递给匿名函数?
【发布时间】:2019-09-07 00:26:52
【问题描述】:

我目前在 Powershell 中使用匿名函数,我注意到从 System.ValueTypeSystem.Object 时出现了一个奇怪的转换问题。

举个例子:

$f = {
    param($InputArray)
    Write-Host "`$Arr Type During Call:" ($InputArray.GetType().FullName)
    Write-Host "`$Arr Contents During Call:" $InputArray
}

[object[]]$Arr = [object[]]@($true, $false)

Write-Host "`$Arr Type Before Call:" ($Arr.GetType().FullName)
Write-Host "`$Arr Contents Before Call:" $Arr "`n"

$f.Invoke($Arr)

以下示例将输出以下内容:

$Arr 调用前的类型:System.Object[]
$Arr 调用前的内容:True False

调用期间的$Arr 类型:System.Boolean
$Arr 通话中的内容:真

看起来 Powershell 将我的变量 $Arr 转换为类型 System.Boolean。如果我强制参数为object[] 类型,就会引入一个新问题:

$f = {
    param([object[]]$InputArray)
    Write-Host "`$Arr Type During Call:" ($InputArray.GetType().FullName)
    Write-Host "`$Arr Contents During Call:" $InputArray
}

[object[]]$Arr = [object[]]@($true, $false)

Write-Host "`$Arr Type Before Call:" ($Arr.GetType().FullName)
Write-Host "`$Arr Contents Before Call:" $Arr "`n"

$f.Invoke($Arr)

新更改产生以下输出:

$Arr 调用前的类型:System.Object[]
$Arr 调用前的内容:True False

调用期间的$Arr 类型:System.Object[]
$Arr 通话中的内容:真

Powershell 只提供我数组的一个元素的匿名函数。这里发生了什么?

  1. 当我明确给它一个 object 数组时,为什么 Powershell 会转换为 boolean
  2. 即使我强制匿名函数的输入参数的类型,为什么Powershell不提供整个数组?

【问题讨论】:

  • 虽然我从来没有发现任何的东西,所以......我认为匿名函数只接受他们得到的第一件事。所以你的代码只看到集合的第一个元素,而不是集合本身。 ///// 我没有文档来支持这一点。 [脸红]
  • 试试这个... >>> $Arr | ForEach-Object {$f.Invoke($_)}
  • @Lee_Dailey:匿名函数是 PowerShell 中的 脚本块,脚本和函数也是脚本块 - 只是命名的。因此,相同的规则在调用时适用于所有这些。这里的问题纯粹是调用语法之一(见我的回答)。通常没有充分的理由在脚本块上使用.Invoke() - 酌情使用&(等效运算符)或.。 Danny 想将一个数组作为一个整体 传递给脚本块,因此您的ForEach-Object 建议将不起作用。

标签: arrays powershell casting anonymous-function data-loss


【解决方案1】:

用途:

$f.Invoke((, $Arr))

或者,更符合 PowerShell 的习惯:

& $f $Arr

至于你尝试了什么

$f.Invoke($Arr)

将数组$Arr 的元素作为单个参数传递。 由于您的脚本块 $f 仅定义 one 参数,因此只有 $Arrfirst 元素绑定到该参数 $InputArray

(, ($Arr)) 通过将数组包装在 auxiliary 单元素数组中来解决该问题,$f.Invoke() 然后解包并因此将 $Arr 作为 single 论据。

也就是说,在 PowerShell 中使用对象 methods 通常是一种尴尬的体验,因为调用语法会导致与 PowerShell 的 command 语法混淆。

通常,可以停留在 PowerShell 的命令和运算符领域。

具体来说,调用脚本块 ({ ... }) 的 PowerShell 惯用方式是使用调用运算符 &(在 child 范围;或者.,点源运算符,(通常)直接在调用者的范围内执行)。

&(和.)使用command 语法(argument 解析模式),其中参数不带括号传递,并用空格 em> 而不是 , - 请参阅 this answer 了解更多信息。

因此,& $f $Arr$Arr 解释为要作为一个整体传递给脚本块的第一个也是唯一一个参数。

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    相关资源
    最近更新 更多