# Define a function that takes an array of integers and
# outputs their hex representation (e.g., '0xa' for decimal 10)
function Get-HexNumber {
param([int[]] $numbers)
foreach ($i in $numbers) {
# Format the integer at hand
# *and implicitly output it*.
'0x{0}' -f $i.ToString('x')
}
}
# Call the function with integers 0 to 16 and loop over the
# results, sleeping 1 second between numbers.
Get-HexNumber (0..16) | ForEach-Object { "[$_]"; Start-Sleep 1 }
1条答案
按热度按时间2uluyalo1#
为什么需要这样做?
这是必需的,因为
BorderAround
method有一个返回值,而且在PowerShell中,任何 * 输出(返回)数据的命令或表达式都是*隐式输出 * 到 (成功)输出流**,默认情况下,输出流将转到 * 主机 *,通常是PowerShell会话运行的 * 控制台窗口 (终端)。也就是说,数据显示在控制台/终端中, 除非 * 是:
$var = ...
)... | ...
;最后管线段命令本身可能产生输出,也可能不产生输出)... >
)、或其任意组合。
那就是:
是(更有效的)简写:
(很少需要显式使用
Write-Output
。)由于您不希望该输出,因此必须 * 抑制 * 它,为此您有以下几种选择:
$null = ...
[void] (...)
... > $null
... | Out-Null
$null = ...
可能是最佳的整体选择,因为:[void] = (...)
也能做到这一点,但由于语法原因,它通常要求您将 expression 括在(...)
中;例如,[void] 1 + 2
没有按预期工作,只有[void] (1 + 2)
;类似地,* 命令 * 必须 * 总是 * 括在(...)
中;[void] New-Item test.txt
不工作,只有[void] (New-Item test.txt)
工作。$null = Get-AdUser ...
)和 * 表达式 * 输出(例如,$null = $range.BorderAround(1, -4138)
)方面都表现良好。相反,避免
... | Out-Null
,因为它通常要慢得多(除了PowerShell(Core)6+中无副作用表达式输出的边缘情况)[1]。但是,如果您需要静默 * 所有 * output streams-不仅是 * 成功 * 输出,还有错误、详细输出... -您必须使用
*> $null
为什么PowerShell会隐式生成输出?
cmd.exe
或Bash等传统shell一样。(传统shell有 2 个输出流- stdout和stderr,而PowerShell有 6 个,以便提供更复杂的功能-请参阅about_Redirection。)*cmdlet、脚本或函数可以根据需要随时写入输出流,并且此类输出通常可 * 立即 * 用于显示,但也可用于潜在的消费者,这支持 * 管道 * 提供的逐个处理。
return
关键字提供,它将输出数据(返回值)与流控制(退出作用域并返回到调用者)合并在一起。return
语句也能起到同样的作用,但实际上并非如此:return <val>
仅仅是<val>; return
的语法糖,即,<val>
的隐式输出之后是控制向调用者的无条件返回;值得注意的是,return
的使用 * 不 * 排除从相同作用域中的较早语句生成输出。echo
的对应物,即Write-Output
,但很少需要使用它。Write-Output
在极少数情况下是有用的,其中包括使用-NoEnumerate
防止在输出上枚举集合,或者使用common parameter-OutVariable
输出数据 * 并 * 将其捕获到变量中(通常只有 * 表达式 * 才需要,因为cmdlet和高级函数/脚本本身支持-OutVariable
)。*隐式输出行为:
一般是 * 福:
[IO.Path]::GetExtension('foo.txt')
和[math]::Pow(2, 32)
这样的表达式-并查看其输出(类似于REPL的行为)。[System.Collections.ArrayList]
类的.Add()
方法意外地生成输出。示例:
以上结果如下:
这演示了该行为的流方面:
Get-HexNumber
的输出可用于ForEach-Object
cmdlet调用,* 因为它正在产生 , 而不是 * 在Get-HexNumber
退出 * 之后。[1]在PowerShell(Core)6+中,如果前面唯一的管道段是 * 无副作用的表达式 * 而不是方法或命令调用,则
Out-Null
具有优化;例如,1..1e6 | Out-Null
几乎没有时间执行,因为表达式看起来甚至没有执行。然而,这样的场景是非典型的,并且功能上等效的Write-Output (1..1e6) | Out-Null
需要很长时间来运行,比$null = Write-Output (1..1e6)
长得多。