Powershell 为什么我的脚本块在执行时被视为字符串,而不是作为脚本执行?
我希望下面的脚本块执行并返回类型为Powershell 为什么我的脚本块在执行时被视为字符串,而不是作为脚本执行?,powershell,Powershell,我希望下面的脚本块执行并返回类型为byte和int的数字,但是引号内的所有内容都变成了字符串而不是脚本 $a=(&{Param($t);"[$t]`$num=10;`$num+=2;`$num"} byte) $a # OUTPUTS STRING [byte]$num=10;$num+=2;$num # NOT NUMBER 12 $ty="int" $b=(&{"[$ty]`$num=5;`$num+=2;`$num"}) $b # OUTPUTS STRING [int]
byte
和int
的数字,但是引号内的所有内容都变成了字符串而不是脚本
$a=(&{Param($t);"[$t]`$num=10;`$num+=2;`$num"} byte)
$a
# OUTPUTS STRING [byte]$num=10;$num+=2;$num
# NOT NUMBER 12
$ty="int"
$b=(&{"[$ty]`$num=5;`$num+=2;`$num"})
$b
# OUTPUTS STRING [int]$num=5;$num+=2;$num
# NOT NUMBER 7
我如何使它按预期工作?
谢谢当您用引号括起来时(请参阅),您正在创建一个字符串:
"[$t]`$num=10;`$num+=2;`$num"
因为这是你们正在组装的,这是你们正在返回的
我假设您正在尝试强制转换为特定类型(int/byte): 您可以改为使用该方法,因为它将为您执行以下操作:
[System.Management.Automation.LanguagePrimitives]::ConvertTo(Object, Type)
我将首先定义脚本块,然后单独调用它:
$a={ codehere }
& $a param1 param2
把这些都带上飞机:
$a={Param($t,$num);$num=[System.Management.Automation.LanguagePrimitives]::ConvertTo($num, $t);$num+2}
& $a byte 5
作为补充,它很好地解释了问题,并包含一个有限制的解决方案[1],具有替代解决方案:
隔离中使用的脚本块确实像匿名函数(它们也是脚本和命名函数的基础)。
虽然不可能使用非文字类型名称的强制转换/类型约束,但您可以使用-as
运算符来实现类似效果:
PS> & { param($t) $num = 10; $num+=2; $num -as $t } byte # !! use -as $t on OUTPUT
12 # type is [byte]
注意事项:
PS> & { param($t) $num = 10; $num+=2; $num -as $t } byte # !! use -as $t on OUTPUT
12 # type is [byte]
- 与PowerShell强制转换不同,
运算符对某些类型敏感,但对其他类型不敏感:例如,它对-as
敏感,但对[datetime]
不敏感[double]
- 这些有问题的不一致性将在中讨论
- 如果无法进行转换,
会安静地返回-as
,因此您可能必须显式处理该情况$null
- 由于
不能用于类型约束变量,因此后续操作可能会更改值的数据类型-as
- 如果执行
后跟$num=10,则会发生这种情况-作为[byte]
:添加将隐式地将类型更改为$num+=2
[int]
- 因此,在输出上应用
运算符,或在必要时在每个中间操作上应用。-as
- 注意复合运算符,如
,其中+=
无法按预期工作;例如,使用-as
代替$num=($num+2)-as[byte]
$num+=2-as[byte]
- 注意复合运算符,如
- 如果执行
- 顺便说一句:如果
支持类型约束,那么它将是一种替代方法,类似于新变量
;它目前没有(从Windows PowerShell v5.1/PowerShell Core 6.1.0开始),但它可以新变量-type$t-Name num-Value 10
或者,使用
[scriptblock]::create()
从字符串表示创建脚本块,这允许您将类型名称“烘焙”到字符串中:
PS> & ([scriptblock]::Create('[{0}] $num=10; $num+=2; $num' -f 'byte'))
12 # type is [byte]
注意事项:
- 仅在您完全控制或信任其内容的字符串上使用此技术,因为可以通过这种方式构造任意命令
- 此外,出于可维护性的考虑,此技术仅适用于小代码段
[1] 不完全等同于演员阵容,因为它不包括