[英]PowerShell: Input Parameter [Array] element automatically/incorrectly converts to wrong datatype
[英]Adding element to array in powershell scriptblock converts array to string
我注意到在脚本块中使用数组的行为异常。 以下代码显示了该问题:
$array = @("x", "y")
Write-Host "$($array.GetType().Name)"
Write-Host "$($array.GetType().BaseType)"
$bad = {
$array += "z"
Write-Host "$($array.GetType().Name)"
Write-Host "$($array.GetType().BaseType)"
$array
}
$good = {
$array = $array.Clone()
$array += "z"
Write-Host "$($array.GetType().Name)"
Write-Host "$($array.GetType().BaseType)"
$array
}
& $good
& $bad
执行脚本将产生以下输出:
Object[]
array
Object[]
array
x
y
z
String
System.Object
z
脚本块$bad
无法正常工作。 它将数组转换为字符串,但应仅将元素z
添加到数组中。 如果未添加任何元素,则可以按预期使用该数组。
我在Powershell 5.0和5.1中注意到了这种现象,但在ISE中却没有注意到。 是一个错误还是有人可以解释?
这是一个范围问题。 脚本块中赋值操作左侧的变量在本地范围内定义。
这个说法
$array = $array.Clone()
克隆全局变量$array
的值,并将其分配给局部变量$array
(名称相同,但由于作用域不同而有所不同)。 然后,局部变量$array
包含原始数组的副本,因此下一条语句
$array += "z"
向该数组追加一个新元素。
在您的另一个脚本块中,您立即将一个字符串附加到(本地)变量$array
。 在这种背景下,局部变量是空的,所以$array += "z"
具有相同的效果$array = "z"
,让你有一个仅包含字符串“Z”的变量。
指定正确的范围,您将获得预期的行为:
$array = @("x", "y")
$not_bad = {
$script:array += "z"
Write-Host "$($script:array.GetType().Name)"
Write-Host "$($script:array.GetType().BaseType)"
$script:array
}
& $not_bad
但是要注意,这实际上会修改global / script范围内的原始数组(您的$good
示例使原始数组保持不变)。
我不确定是否会将此行为视为错误,但这绝对是一个陷阱。
我想根据Ansgars的说明发布我的首选解决方案:
$array = @("x", "y")
$not_bad = {
$array = $array + "z"
Write-Host "$($array.GetType().Name)"
Write-Host "$($array.GetType().BaseType)"
$array
}
& $not_bad
重要的是在添加其他元素之前分配给局部变量(或者更好地创建局部变量)。 一个简单的
$array = $array
可以,但是这行可能会造成混淆。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.