二进制位运算符和使用规则:
位运算符号名称规则例子(二进制)&与运算符相同位的两个数字都为1,则为1;若有一个不为1,则为01&1=1; 1&0=0; 0&0=0; 0&1=0;|或运算符相同位只要一个为1即为11|1=1; 1|0=1; 0|0=0; 0|1=1;^异或运算符相同位不同则为1,相同则为01^1=0; 1^0=1; 0^0=0; 0^1=1;~取反运算符0和1全部取反~1=0;~0=1<<左移运算右边空出的位用0填补,高位左移溢出则舍弃该高位1 << 1 = 10>>右移运算左边空出的位用0或者1填补。正数用0填补,负数用1填补。低位右移溢出则舍弃该位
GO实现
package main
import (
"fmt"
)
const(
System = 1
Baidu = 1<<1
Ali = 1<<2
)
// 存储目前的权限状态
type Check struct {
Flag int
}
// 设置状态
func (c *Check)SetStatus(status int){
c.Flag = status
}
// 添加一种或多种状态
func (c *Check)AddStatus(status int){
c.Flag |= status
}
// 删除一种或者多种状态
func (c *Check)DeleteStatus(status int) {
/**
go 不支持取反符号~
c.Flag &= ~status
取反 ^status
*/
c.Flag &= ^status
}
// 是否具有某些状态
func (c *Check)HasStatus(status int) bool{
return (c.Flag & status) == status
}
// 是否不具有某些状态
func (c *Check)NotHasStatus(status int) bool {
return (c.Flag & status) == 0
}
// 是否仅仅具有某些状态
func (c *Check)OnlyHas(status int) bool {
return c.Flag == status
}
func main(){
c := Check{Flag: 0}
c.SetStatus(3) // 011
fmt.Printf("3=>011 --> has system %t, and baidu %t, and ali %t\n", c.HasStatus(System),c.HasStatus(Baidu),c.HasStatus(Ali))
c.AddStatus(Ali)
fmt.Printf("3=>011 add ali --> has system %t, and baidu %t, and ali %t\n", c.HasStatus(System),c.HasStatus(Baidu),c.HasStatus(Ali))
c.DeleteStatus(Baidu)
fmt.Printf("3=>011 add ali and delete baidu --> has system %t, and baidu %t, and ali %t\n", c.HasStatus(System),c.HasStatus(Baidu),c.HasStatus(Ali))
fmt.Printf("3=>011 add ali and delete baidu --> not has system %t, and not has baidu %t, and not has ali %t\n", c.NotHasStatus(System),c.NotHasStatus(Baidu),c.NotHasStatus(Ali))
fmt.Printf("3=>011 add ali and delete baidu --> only has system %t\n",c.OnlyHas(System))
c.DeleteStatus(Ali)
fmt.Printf("3=>011 add ali and delete baidu and delete ali --> only has system %t\n",c.OnlyHas(System))
}
解析
AddStatus
|或运算符结果(System and Baidu)3 | Ali(4)011 | 100 = 1117 拥有三者权限
DeleteStatus
&与运算符结果(System and Baidu and Ali)7 & (^Baidu(2))111 & (^100) = 111 & 1011 = 00113 system and baidu
HasStatus
&与运算符结果(System and Baidu)3 | Baidu(2)011 & 010 = 0102==Baidu(2) 拥有Baidu权限