Powershell 中的显式返回



我可以用javascript编写以下代码:

function sum(num1, num2) {
return num1 + num2;
}

然后获取一个值

var someNum = sum(2,5);

我想在Powershell中做同样的事情,但我阅读了以下指南:

PowerShell也知道返回关键字;但是,它遵循一个 不同的逻辑。一般来说,回归的目的是结束 执行代码节并将控制权交还给父级 块。

如果将参数添加到 return 语句中,该值确实会 返回到调用子例程。但是,这也适用于 所有其他带有输出的语句。这意味着任何输出 在函数中产生的将与变量一起存储在变量中 返回参数。

我想这样做是为了拥有纯粹的功能。然而,它似乎在做

var someNum = sum(2,5);

完全是多余的,当我可以调用上面的函数,在其中定义someNum,它将在全局范围内可用。

我是否缺少某些内容,或者是否可以在Powershell中编写不返回函数内所有内容的纯函数?


有点切线,但这是我的实际代码:

function GetPreviousKeyMD5Hashes() {
$query = "SELECT Name, MD5, executed FROM [AMagicDb].[dbo].cr_Scripts";
$command = New-Object System.Data.SQLClient.SQLCommand;
$command.Connection = $connection;
$command.CommandText = $query;
try {
$reader = $command.ExecuteReader();
while ($reader.Read()) {
$key = $reader.GetString(1)
$previousScripts.Add($key) | Out-Null
}
$reader.Close();
Write-Output "$(Get-Date) Finished querying previous scripts"
}
catch {
$exceptionMessage = $_.Exception.Message;
Write-Output "$(Get-Date) Error running SQL at with exception $exceptionMessage"
}
}

然后:

$previousScripts = New-Object Collections.Generic.HashSet[string];
GetPreviousKeyMD5Hashes;

这段代码对我来说根本不清楚 - 运行GetPreviousKeyMD5Hashes确实设置了$previousScripts,但是在我之后修改它的人完全不清楚。我唯一的其他选择(afaik(是将所有这些放在一起,这也是不可读的。

是完全多余的,当我只需调用上面的函数,在其中定义 someNum,它将在全局范围内可用。

否:函数在作用域中执行(除非您使用.对它们进行点源(,因此在函数中创建或分配给的变量是其本地的

我是否缺少某些内容,或者是否可以在Powershell中编写不返回函数内所有内容的纯函数?

是:隐式输出行为仅适用于其输出既未捕获-$var = ...- 也不重定向-... > foo.txt的语句

如果某些语句恰好生成要放弃的输出,请使用$null = ...... > $null

注意:... | Out-Null原则上也可以工作,但通常性能会更差,尤其是在早期的PowerShell版本中 - 谢谢,TheIncorrigible1。

如果您想在不成为输出的一部分的情况下写入状态消息,请使用Write-Host或者,最好是Write-Verbose,或者在 PSv5+ 中,Write-Information,但请注意,后两者需要选择加入才能在控制台中显示其输出。
不要使用Write-Output写入状态消息,因为它会写入成功输出流,其用途是输出数据("返回值"(。
有关PowerShell输出流的更多信息,请参阅我的这个答案。

因此,您的 JavaScript 代码的等效项是:

function sum($num1, $num2) {
Write-Host "Adding $num1 and $num2..."  # print status message to host (console)
$num1 + $num2 # perform the addition and implicitly output result
}
PS> $someNum = sum 1 2 # NOTE: arguments are whitespace-separated, without (...)
Adding 1 and 2...  # Write-Host output was passed through to console
PS> $someNum  # $someNum captured the success output stream of sum()
3

我是否缺少某些东西,或者是否可以在 Powershell 中编写不返回函数内所有内容的纯函数?

你不能一边吃蛋糕一边吃...

如果你的函数没有输出,那么它就像你想要的那样"纯粹"。 如果您有输出,这也将成为回报的一部分。

您可以使用[ref]参数。 例如,请参见下文。

function DoStuff([ref]$refObj)
{
Write-Output "DoStuff: Enter"
$refObj.Value += $(1 + 2)
$refObj.Value += "more strings"
Write-Output "DoStuff: Exit"
}
$refRet = @()
$allRet = DoStuff([ref]$refRet)
"allRet"
$allRet
"refRet"
$refRet
"`n`nagain"
$allRet = DoStuff([ref]$refRet)
"allRet"
$allRet
"refRet"
$refRet

注意:Powershell 不需要在每个语句的末尾使用分号;仅用于在同一行上分隔多个语句。

只要有可能,最好避免更改函数中的全局状态。 将输入作为参数传递,并返回输出,这样您就不会局限于仅以一种方式使用该函数。 您的示例可能如下所示:

function sum
{
param($num1,$num2)
return $num1+$num2
}
$somenum=sum 2 5

现在,使用 Powershell,不需要 return 语句。 未以其他方式分配、捕获、重定向或以其他方式使用的每个语句的结果只是与返回值一起抛出。 因此,我们可以将上面的 return 语句替换为

$num1+$num2

您已经在代码中使用它:

$previousScripts.Add($key) | Out-Null

您丢弃.Add()的结果的地方. 否则,它将包含在返回值中。

就个人而言,我发现使用return显式标记返回值使其更易于阅读。 Powershell 将所有输出放入返回中的方式在我学习时给我带来了很多麻烦。

因此,我要对您的代码进行的唯一修复是:

$previousScripts = New-Object Collections.Generic.HashSet[string]移动到函数内部,使其本地化。

return $previousScripts添加到函数的末尾。

相关内容

  • 没有找到相关文章

最新更新