为啥将“switch”类型参数的值传递给字符串参数?
Posted
技术标签:
【中文标题】为啥将“switch”类型参数的值传递给字符串参数?【英文标题】:Why is the value of "switch" type parameter passed to a string parameter?为什么将“switch”类型参数的值传递给字符串参数? 【发布时间】:2018-01-23 07:36:21 【问题描述】:测试代码(test.ps1
):
Param(
[string]$content = $null,
[switch]$flag = $false
)
Write-Host $content
输出:
PS C:\Users\powershell> .\test.ps1 PS C:\Users\powershell> .\test.ps1 -flag $true 真的 PS C:\Users\powershell> .\test.ps1 -flag $false 错误的 PS C:\Users\powershell> .\test.ps1 -flag $true -content "lalala" 拉拉拉无论我将$content
设置为$null
,还是""
,或者没有任何默认值,输出都是一样的。
那么为什么$content
会从$flag
中取值呢?
【问题讨论】:
你没有向-flag
传递任何值。
开关参数,在它们的一般用法中,如果你不在命令行中指定它们,则为 $false,如果你在命令行中指定它们,则为 $true。 @PetSerAl
我无法重现此问题,您使用的是什么 psversion?什么操作系统?
我认为这里真正的混淆点是 $true
被解析器解释为位置参数并隐式绑定到 -Content
【参考方案1】:
@PetSerAl已经指出你的误解是什么,但可能有点太简短了,所以我再详细说明一下。
[switch]
参数不像常规参数那样采用值。您通常通过提供或省略参数将其分别设置为 true 或 false:
或者,您可以通过在开关参数和值之间放置冒号来显式传递值:
PS C:\> .\test.ps1 -Flag:$false 错误的 PS C:\> .\test.ps1 -Flag:$true 真的允许冒号后面的空格,但前面不允许(-Flag: $false
将 $false
作为开关值传递,-Flag :$false
则不允许)。
如果您尝试分配开关值 没有冒号,则该值实际上传递给行中的下一个参数,在您的情况下为 -Content
参数:
如果您使用-Flag $true
(不带冒号)并且将值传递给(命名的)参数-Content
,则值$true
作为未命名的第三个参数传递(可通过automatic variable$args
),就像你把值放在语句的末尾一样:
【讨论】:
冒号后面可以有空格。【参考方案2】:运行这个测试代码,像在问题中那样调用它。添加这个测试:
C:\Users\powershell> .\test.ps1 -flag
脚本将说明以下几点:
根据 4c74356b41 的注释,除非在命令行中指定,否则开关为$false
。所以-flag
将$flag
开关设置为true; -flag $true
将标志设置为真并且将参数$true
传递给内容。
由此,无需在脚本参数中指定$flag=$false
添加了一个测试,以便您可以看到$content
何时为空/null,因为也不需要$content=$null
param(
[string]$content,
[switch]$flag
)
$test = [string]::IsNullOrEmpty($content)
Write-Output "content: $content"
Write-Output "flag : $flag"
Write-Output "Is content null: $test"
【讨论】:
【参考方案3】:我将补充一点,您也可以通过 splatting 分配值,通过 splat 参数分配将值从 $true 更改为 $false 将改变您的开关“检测”。当您使用另一个值或属性来确定是否应该使用开关时,这很有用。
function FooBar
param (
[switch]
$Foo
)
if ($Foo)
"Foo"
else
"Bar"
$splat = @
Foo = $False
FooBar @splat
【讨论】:
以上是关于为啥将“switch”类型参数的值传递给字符串参数?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我们将字符串数组作为参数传递给 main() 方法,为啥不传递任何集合类型或包装类型或原始类型?
为啥将字符串文字传递给 char* 参数有时只是编译器错误?
如何通过 FromQuery 参数将“System.Object”类型传递给控制器