小心PowerShell的类型转换陷阱


PowerShell的类型转换非常的方便。PowerShell解释器会根据类型之间可能存在的转换规则尽自己最大的努力实现类型转换。这样对于脚本使用者来讲的确是利大于弊,因为它方便,举个例子。

PS> $a=3/2
PS> $a.GetType().fullname
System.Double
PS> $a=[decimal]3/2
PS> $a
1.5
PS> $a.gettype().fullname
System.Decimal
PS> $a=3/3
PS> $a.gettype().fullname
System.Int32

我们使用时都不需要关心a是什么类型,PowerShell觉得它是什么类型,它就是什么类型。

我有提到,利大于弊。弊端在于,这些类型转换都是无声的,不像我们写C#时,有明确指定Converter,否则编译不过。如果用户经验不足,极有可能被PowerShell的转换器带到沟里。

比如最简单的3/2的问题:

PS> 3/2
1.5
PS> [int](3/2)
2

乍一看,合情合理,没什么大问题啊。那么大家回忆一下,在C#中

 int a=3/2;

a的值应当是1,而不是2。

显然,PowerShell判断3/2得到的值为1.5,然后它认为1.5是double,接下来我们用了【int】做转换类型,PowerShell发现在dobule和int之间存在一个转换器:

static int ToInt32(double value)

然后它就调用了:

PS> [convert]::ToInt32(1.5)
2

结果做了四舍五入后,变成2,也能讲到通。

但是如果我们只是想单纯的像C#那样向下取整呢?那还得用大招,PowerShell的自动类型转换靠不住。

PS> [math]::Floor(3/2)
1
PS> [math]::Floor(1.8)
1
PS> [math]::Floor(1.9999)
1

这样的类型转换陷阱,不可以小觑,就像3/2到底是给向下取整还是该向上取整,作为脚本开发者应当自己心里有本经,推荐显式地的调用Floor或者Ceiling方法。

×用微信扫描并分享
本文链接: https://www.pstips.net/type-convert-trap.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

发表评论

邮箱地址不会被公开。 必填项已用*标注