[string] :: Format和-f以及Array vs split运算符之间的区别

时间:2018-05-13 22:49:18

标签: powershell

我编写了这段代码,以显示格式化字符串方法的不同之处:

使用Split

的示例
$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块失败并移动到可用的第二个版本的命令。

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

1 个答案:

答案 0 :(得分:3)

如果你看一下[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[]],即使它可能是?

由于这种过载:

static string Format(string format, 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[];