Dmi*_*hev 4 powershell type-conversion powershell-core
最近我发现了一些关于在 Powershell 中将一些类似版本的值分配给变量的令人讨厌的行为(至少在 7.2.5 中)。
起初我尝试过:
> $version = 1.2.3
> echo $version
Run Code Online (Sandbox Code Playgroud)
我很快发现我必须用引号转义 thr 值才能显式地使其成为字符串。这个效果很好:
> $version = "1.2.3"
> echo $version
1.2.3
Run Code Online (Sandbox Code Playgroud)
问题是:为什么会这样?为什么pwsh在第一个示例中不抛出某种错误而只是将其转换为$null?就像其他情况一样:
> 12a
12a: The term '12a' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
> [int]12a
ParserError:
Line |
1 | [int]12a
| ~~~
| Unexpected token '12a' in expression or statement.
Run Code Online (Sandbox Code Playgroud)
所以我相信像这样的文字1.2.3 是由某种规则所期望和管理的。我试图深入研究有关表达式和赋值的文档,但找不到正确的答案。
为什么会这样?
实际上,1.2.3被解析为(1.2).3,即作为其属性被检索的数字文字。 1.2.3
数字文字是( ,双精度浮点值)1.2的实例,因此没有属性(或任何其他属性)。[double]System.Double .3
$null默认情况下,当您尝试访问对象上不存在的属性时,PowerShell 会悄悄返回。
正如Santiago Squarzon指出的,如果您使用或更高版本,您可以将此类尝试转变为(语句终止)错误:Set-StrictMode -Version 2
PS> Set-StrictMode -Version 2; 1.2.3
... The property '3' cannot be found on this object. ...
Run Code Online (Sandbox Code Playgroud)
笔记:
给定的严格模式对整个作用域和任何后代作用域生效。
请注意,如果脚本或非模块函数在设计时没有考虑到这种严格模式,这可能会使调用脚本或非模块函数失败(代码通常假设没有严格模式生效)。
要关闭活动的严格模式,请使用Set-StrictMode -Off
由于长期存在的错误 - 请参阅GitHub 问题 #2798和#16427 -内部成员 .Count和.Length- 对于统一处理集合和标量有用 - 然后不可用。
事实上,严格模式版本 2 或更高版本会因尝试访问不存在的属性而导致语句终止错误,这意味着默认情况下会继续执行下一条语句。
请参阅下面iRon的评论,获取 GitHub 问题的链接,这些问题讨论了手头可能令人惊讶的行为(1.2.3悄悄地评估为$null),以及实现PSScriptAnalyzer规则的建议的链接,该规则将警告诸如 之类的表达式1.2.3,以便您例如,在 Visual Studio Code 中编辑代码时收到设计时警告。
最后,如果您想创建1.2.3为版本对象,您可以从字符串进行转换:
[version] '1.2.3'创建一个System.Version实例。
仅限 PowerShell(核心)7+:[semver] '1.2.3'创建System.Management.Automation.SemanticVersion实例。
| 归档时间: |
|
| 查看次数: |
290 次 |
| 最近记录: |