具有类型赋值的添加成员怪异 [英] add-member weirdness with type assignment
问题描述
$name1 = 4
$name2 = 4
$name3 = 4
$myObject = New-Object System.Object
$myObject | Add-Member -type NoteProperty -name name1 -Value [int]$name1
$myObject | Add-Member -type NoteProperty -name name2 -Value $($name2 -as [int])
$myObject | Add-Member -type NoteProperty -name name3 -Value $([int]$name3)
$myObject
输出:
name1 name2 name3
----- ----- -----
[int]4 4 4
Powershell版本:
get-host | select-object version
Version
-------
5.1.19041.1023
推荐答案
现有答案中有很好的信息,但让我尝试系统地概述一下:
tl;dr
为了将表达式(例如 相反, PowerShell有两种基本解析模式: 参数模式,其工作方式与类似shell。 表达式模式,类似编程语言,字符串必须用引号括起来,可以使用赋值、 概念性 给定的语句可能由在任一模式下解析的部分组成,这确实是上面发生的情况: 因为您的语句以命令名( 被认为是元字符(具有特殊语法意义的字符)在不同的分析模式中不同: 相反,标记-initial 复合参数 某些表达式用作命令参数(假设 请注意,这些参数与其原始数据类型一起传递,而不是字符串(尽管字符串可以由接收命令执行)。 陷阱: 有时需要显式使用 如果将 同样,仅当参数以不带引号的标记开头(例如, 简而言之: 参数解析的确切规则很复杂: 为安全起见,避免在[int] $name1
)、或(嵌套)命令(例如Get-Date -Format yyyy
)作为参数传递给命令(例如Add-Member
),将其括在(...)
Add-Member -type NoteProperty -name name1 -Value ([int] $name1)
$(...)
在此方案中通常不需要subexpression operator,使用它可能会产生副作用-请参阅this answer。
"..."
之外),您只需要$(...)
将语言语句括起来(如if
语句或foreach
循环)或多个语句(命令、表达式和语言语句的任意组合,用;
分隔)。
PowerShell的解析模式:
.ps1
脚本的路径名称),后跟以空格分隔的参数列表,其中字符串可以是不带引号的[1]foreach
和while
循环等运算符和语言语句,强制转换。about_Parsing
介绍这些模式;简而言之,它是给定上下文中的第一个内标识,它决定应用哪种模式。
Add-Member
)开头,所以它以参数模式进行分析。(...)
强制新的解析上下文,在当前情况下([int] $name1
)以表达式模式解析,因为以[
开头)。
[
和=
仅在表达式模式中特殊,而在参数模式中不特殊,在该模式下,它们将逐字使用。@
后跟变量name仅在参数模式下特殊,在该模式下它用于参数splatting。[int]$name1
因此被视为可扩展字符串,并导致逐字字符串[int]4
。$var = 'Foo'
)时,不需要括在(...)
中:
Write-Output $var
或Write-Output $env:OS
)Write-Output $var.Length
)Write-Output $var.ToUpper()
)
"..."
以取消属性访问解释,并逐字解释变量引用后面的.
(例如Write-Output "$var.txt"
以便逐字解释foo.txt
)。$(...)
用作复合参数的一部分,而不使用显式"..."
引号,则如果$(...)
子表达式开始该参数(例如,Write-Output $('a' + 'b')/c
传递两个参数,即逐字ab
和/c
),则该参数将被拆分为多个参数(例如,Write-Output $('a' + 'b')/c
传递两个参数,即逐字ab
和/c
Write-Output One"$var"'$Two'
按预期工作并逐字生成OneFoo$Two
,但Write-Output 'One'"$var"'$Two'
作为三个参数、逐字One
、Foo
和$Two
)开始时,混合使用带引号和不带引号的字符串以形成单个参数才有效。
"..."
外部使用$(...)
,并避免在单个字符串参数中混合引用样式;在表达式中使用(单)"..."
字符串(例如Write-Output "$(Split-Path $PROFILE)/foo.txt"
或)或字符串连接(Write-Output ('One' + $var + '$Two')
[1]假设它们既不包含空格,也不包含PowerShell的任何元字符(请参见this answer)。虽然引号通常采用根据需要将整个参数括在单引号或双引号中(例如'foo bar'
、"foo $var"
)的形式,但也可以使用反号(`
)引出(转义)单个字符(例如foo` bar
),这是PowerShell的转义字符。
这篇关于具有类型赋值的添加成员怪异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!