Powershell的-split在不同的方法参数下表现不同。

huangapple go评论104阅读模式
英文:

Powershell's -split behaves differently depending on method parameters

问题

如果你分割一个字符串,你会得到一个字符串数组。

$foo = "apple,banana,coconut"
Write-Output $foo.GetType()

$foo = $foo -split ","
Write-Output $foo.GetType()

如果你分割一个带参数的字符串,你会得到一个字符串。

Function Get-Foo() {
    param ( 
        [string] $foo
    )

    Write-Output $foo.GetType()

    $foo = $foo -split ","
    Write-Output $foo.GetType()
}

为什么?

我进行了研究,但没有找到任何有用的信息;PowerShell 的分割文档基本没有帮助。

英文:

If you split a string, you get a string[].

$foo = "apple,banana,coconut"
Write-Output $foo.GetType()

$foo = $foo -split ","
Write-Output $foo.GetType()

If you split a paramaterized string, you get a string.

Function Get-Foo() {
    param ( 
      [string] $foo
    )

    Write-Output $foo.GetType()

    $foo = $foo -split ","
    Write-Output $foo.GetType()
}

Why?

I researched this and didn't turn anything up; Powershell's documentation on split was largely unhelpful.

答案1

得分: 5

以下是翻译好的部分:

在你的第一个示例中,不同之处在于你从未声明过该变量,因此可以将任何类型的值分配给它,它将接受它们而不需要强制转换,从而改变其类型以匹配:

PS > $foo = "apple,banana,coconut"
PS > Write-Output $foo.GetType().Name
String
PS > $foo = $foo -split ","
PS > Write-Output $foo.GetType().Name
String[]
PS > $foo = 1
PS > Write-Output $foo.GetType().Name
Int32

但是,一旦你使用 [string] 明确声明了 $foo 的类型,$foo.GetType() 将继续报告 string,你分配给它的任何内容都将被强制转换为 string。你不能仅通过分配新值来更改已声明变量的类型:

PS > [string] $foo = "apple,banana,coconut"
PS > Write-Output $foo.GetType().Name
String
PS > $foo = $foo -split ","
PS > Write-Output $foo.GetType().Name
String
PS > $foo = 1
PS > Write-Output $foo.GetType().Name
String

不过,你可以通过重新声明来更改类型,即使在函数内也可以:

PS > [Int32] $foo = $foo
PS > Write-Output $foo.GetType().Name
Int32

请注意,如果值无法解释为新类型,则此重新声明分配将失败:

PS > [string] $foo = "apple,banana,coconut"
PS > [Int32] $foo = $foo
无法将值 "apple,banana,coconut" 转换为类型 "System.Int32"。错误: "输入字符串不符合要求的格式。"

据我所知,除非完全删除该变量(使用 Remove-Variable),否则没有办法“取消声明”变量的类型,使其恢复接受任何类型的值。

英文:

The difference is that in your first example, you never declared the variable, so you can assign it values of any type and it will accept them without coercion, altering its type to match:

PS > $foo = "apple,banana,coconut"
PS > Write-Output $foo.GetType().Name
String
PS > $foo = $foo -split ","
PS > Write-Output $foo.GetType().Name
String[]
PS > $foo = 1
PS > Write-Output $foo.GetType().Name
Int32

But once you've explicitly declared $foo's type with [string], $foo.GetType() will continue to report string, and anything you assign to it will be coerced to string. You can't change the type of a declared variable just by assigning it a new value:

PS > [string] $foo = "apple,banana,coconut"
PS > Write-Output $foo.GetType().Name
String
PS > $foo = $foo -split ","
PS > Write-Output $foo.GetType().Name
String
PS > $foo = 1
PS > Write-Output $foo.GetType().Name
String

You can change the type by re-declaring it, though. Even within a function:

PS > [Int32] $foo = $foo
PS > Write-Output $foo.GetType().Name
Int32

Note that such a redeclaration assignment will fail if the value is not interpretable as the new type:

PS > [string] $foo = "apple,banana,coconut"
PS > [Int32] $foo = $foo
Cannot convert value "apple,banana,coconut" to type "System.Int32". Error: "Input string was not in a correct format."

As far as I know, there's no way to "un-declare" a variable's type so it goes back to accepting any type of value, short of removing the variable entirely with Remove-Variable.

huangapple
  • 本文由 发表于 2020年1月6日 23:59:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/59615208.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定