在 PowerShell 5 中,对枚举的新支持特性使得处理比特位比您在前面的 PowerShell 技能中看到的简单得多。现在设置或清除比特位不再需要冗长的逻辑操作符。
我们先定义一个枚举类型,这样更好管理十进制数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
[Flags()] enum GardenPartyItems { Chair = 0 Table = 1 Barbecue = 2 Fridge = 4 Candle = 8 Knife = 16 }
$decimal = 11 [GardenPartyItems]$flags = $decimal $flags
|
现在,十进制数的比特位可以很容易地转化为 GardenPartyItem 的列表:
1 2 3 4
| PS C:\> [GardenPartyItems]11 Table, Barbecue, Candle
PS C:\>
|
注意:将十进制数转换为枚举型时,请确保枚举型中定义了所有的比特。如果十进制数太大,包含枚举型之外的比特时,转换会失败。
要增加一个新的标志位,请试试以下的代码:
1 2 3 4 5 6 7 8 9
| PS C:\> $flags Table, Barbecue, Candle
PS C:\> $flags += [GardenPartyItems]::Knife
PS C:\> $flags Table, Barbecue, Candle, Knife
PS C:\>
|
要移除一个标志位,请试试以下代码:
1 2 3 4 5 6 7 8 9
| PS C:\> $flags Table, Barbecue, Candle, Knife
PS C:\> $flags -= [GardenPartyItems]::Candle
PS C:\> $flags Table, Barbecue, Knife
PS C:\>
|
然而,实际上并没有看起来这么简单。当移除一个已有的标志位,没有问题。但移除一个没有置位的标志位,会把比特值搞乱:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| PS C:\> $flags Table, Barbecue, Candle
PS C:\> $flags -= [GardenPartyItems]::Candle
PS C:\> $flags Table, Barbecue
PS C:\> $flags -= [GardenPartyItems]::Candle
PS C:\> $flags -5
PS C:\>
|
所以 PowerShell 在自动处理二进制算法方面明显还不够智能。要安全地使用该功能,您还是要用二进制操作符。要移除标志位,请使用 -band
和 -bnot
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| PS C:\> $flags Table, Barbecue, Candle
PS C:\> $flags = $flags -band -bnot [GardenPartyItems]::Candle
PS C:\> $flags Table, Barbecue
PS C:\> $flags = $flags -band -bnot [GardenPartyItems]::Candle
PS C:\> $flags Table, Barbecue
PS C:\>
|
要设置标志位,请使用 -bor
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| PS C:\> $flags Table, Barbecue, Candle
PS C:\> $flags = $flags -bor [GardenPartyItems]::Knife
PS C:\> $flags Table, Barbecue, Candle, Knife
PS C:\> $flags = $flags -bor [GardenPartyItems]::Knife
PS C:\> $flags Table, Barbecue, Candle, Knife
PS C:\>
|
在所有这些操作中,实际上是在操作一个十进制数:
相当棒,对吧?