我编写此代码是为了展示格式化字符串方法的差异:
使用拆分的示例
$arr = 'that,way'
$arr = $arr -split ","
$arr.GetType()
$arr.Count
try {
$rundmc = [string]::format("It's like {0} and that's the {1} it is",$arr)
}
catch {
Write-Host "String::format failed"
$rundmc = "It's like {0} and that's the {1} it is" -f $arr
}
Write-Host $rundmc
将输入数组定义为实际数组的示例
$arr2 = @('that','way')
$arr2.GetType()
$arr2.Count
try {
$rundmc = [string]::format("It's like {0} and that's the {1} it is",$arr2)
}
catch {
Write-Host "String::format failed"
$rundmc = "It's like {0} and that's the {1} it is" -f $arr2
}
Write-Host $rundmc
在前半部分,try
block 失败并转移到有效命令的第二个版本。
powershell 中的[string]::Format
和 -f
运算符有什么区别?
该命令的第一个版本失败:
$rundmc = [string]::format("It's like {0} and that's the {1} it is",$arr)
Exception calling "Format" with "2" argument(s): "Index (zero based) must be greater than or equal to zero and less than the size of the argument list."
At line:1 char:1
+ $rundmc = [string]::format("It's like {0} and that's the {1} it is",$ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FormatException
但是-f
有效。对我来说,它们看起来相当相似。
两种数据类型之间的差异:
拆分
获取类型IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String[] System.Array
数数
2
数组
获取类型IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
数数
2
最佳答案
如果您查看 [string]::Format
的重载:
OverloadDefinitions ------------------- static string Format(string format, System.Object arg0) static string Format(string format, System.Object arg0, System.Object arg1) static string Format(string format, System.Object arg0, System.Object arg1, System.Object arg2) static string Format(string format, Params System.Object[] args) static string Format(System.IFormatProvider provider, string format, System.Object arg0) static string Format(System.IFormatProvider provider, string format, System.Object arg0, System.Object arg1) static string Format(System.IFormatProvider provider, string format, System.Object arg0, System.Object arg1, System.Object arg2) static string Format(System.IFormatProvider provider, string format, Params System.Object[] args)
您可以看到您尝试使用的就是这个:
static string Format(string format, Params System.Object[] args)
请注意,它期望其值是一个对象数组。
当您使用 -split
运算符时,如您所见,结果是 [String[]]
,而不是 [Object[] ]
。
$arr = 'that,way'
$arr = $arr -split ","
$arr.GetType()
$arr -is [Object[]] # false
为什么它没有被强制转换为 [Object[]]
,即使它可以这样做?
由于这种重载:
静态字符串格式(字符串格式,System.Object arg0)
$arr -isnot [Object[]]
但是 $arr -is [Object]
,因此此重载完全匹配。
不幸的是,由于您的格式字符串包含 2 个替换,并且您调用了仅提供 1 个替换的重载,因此您会收到此错误。
如果您执行了 [String]::Format('Just 1: {0}', $arr)
您的调用将会成功(但结果将是 Just 1: System.String[]
因为在参数上调用了 .ToString()
方法)。
由于 PowerShell 中的大多数数组最终都为 [Object[]]
,因此在定义文字数组或将数组指定为管道的输出时,它会起作用。
例如,如果您执行以下任一操作,您仍然可以使用 [String[]]
版本的 $arr
:
[String]::Format('{0}~{1}', $($arr))
[String]::Format('{0}~{1}', ([Object[]]$arr))
[String]::Format('{0}~{1}', ($arr -as [Object[]]))
[String]::Format('{0}~{1}', ($arr|%{$_}))
-f
运算符怎么样?
Let's look at the source code for it .
它所做的第一件事就是尝试将其参数转换为 object[]
:
object[] formatArgsArray = formatArgs as object[];
关于powershell - [string]::Format 和 -f 之间的区别,以及数组与分割运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50321268/