假设我尝试将字符串分配给强类型的整数变量:
[int]$bar = '1'
这很有效,因为PowerShell能够将字符串'1'
强制转换为整数。
现在情况有所不同,如果我尝试使用强类型布尔变量:
[boolean]$foo = 'foo'
Cannot convert value "System.String" to type "System.Boolean". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1
or 0.
我发现这令人困惑,因为PowerShell同时允许从字符串显式转换为布尔值:
[boolean]'foo'
True
有谁知道这种看似不一致行为的原因?
答案 0 :(得分:4)
在大多数情况下,我会争论以下方法,而不是键入变量:在赋值之前将值转换为目标类型,然后让类型系统推断变量类型:
$foo = [bool]"foo"
$foo = "foo" -as [bool]
$foo = $true -eq "foo"
(这不是一个权威的答案,但最好的猜测)
about_Variables
帮助文件中简要提及:
变量类型
您可以将任何类型的对象存储在变量[...]
中Windows PowerShell变量是“松散类型”,这意味着 它们不限于特定类型的对象。 [...]
[...关于价值推断类型的部分bla bla bla ...]
您可以使用类型属性并使用强制转换符号来确保a 变量只能包含指定类型或对象的对象 可以转换为该类型。如果您尝试分配值 在另一种类型中,Windows PowerShell尝试将值转换为 它的类型。如果不能,则赋值语句失败。
要使用强制表示法,请在之前输入括在括号中的类型名称 变量名称(在赋值语句的左侧)。
虽然“type attribute”和仅在赋值期间适用的不同约束在文档中没有使用,但(至少对我来说)表明这是显式转换的特例。
在变量中添加显式强制转换表示法时,如上所述,PowerShell会在变量中添加ArgumentTypeConverterAttribute
,并突然覆盖PowerShell的type conversion magic通过特定于类型的Transform()
方法:
PS C:\> $var = 5
PS C:\> Get-Variable var |fl *
Name : var
Description :
Value : 5
Visibility : Public
Module :
ModuleName :
Options : None
Attributes : {}
PS C:\> [int]$var = 5
PS C:\> Get-Variable var |fl *
Name : var
Description :
Value : 5
Visibility : Public
Module :
ModuleName :
Options : None
Attributes : {System.Management.Automation.ArgumentTypeConverterAttribute}
如果我们使用布尔类型重复此实验,您可以看到ArgumentTypeConverterAttribute
转换比正常转换“魔法”更具限制性:
PS C:\> [bool]$foo = $true
PS C:\> (Get-Variable foo).Attributes[0].Transform($ExecutionContext,"foo")
Exception calling "Transform" with "2" argument(s): "Cannot convert value "System.String" to type "System.Boolean". Boolean parameters
accept only Boolean values and numbers, such as $True, $False, 1 or 0."
At line:1 char:1
+ (Get-Variable foo).Attributes[0].Transform($ExecutionContext,"foo")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentTransformationMetadataException
再次在这种类型的转换中布尔参数只接受布尔值和数字,例如$ True,$ False,1或0。,而powershell本身通常会解释任何非空的,非隐式转换为$true
时,零或非空值为[bool]
。
换句话说:
[bool]$SomeVariable = [bool]"bar"
^ ^ ^
| | |
| during assignment |
This is a type attribute|
This is a cast notation
即使他们看起来一样