本文共 2553 字,大约阅读时间需要 8 分钟。
之前一直忽略的就是所有语言中关于位操作,觉得用处并不多,可能用到也非常简单的用法,但是其实一直忽略的是它们的用处还是非常大的,下面先回顾一下位操作符的基础
与操作:&
1 & 1 = 11 & 0 = 00 & 1 = 00 & 0 = 0或操作:!
1 | 1 = 11 | 0 = 10 | 1 = 10 & 0 = 0异或:^
1 ^ 1 = 01 ^ 0 = 10 ^ 1 = 10 ^ 0 = 0左移:<<
1 << 10 = 10241 << 20 = 1M1 << 30 = 1G右移:>>
1024 >> 10 = 11024 >>1 = 5121024 >>2 = 256
可能这个例子在实际中用并不是特别严谨,但是也提供了我们写代码的一种思路
这里拿微博或者qq用户的特权为例子:
一个qq号可以用VIP会员,SVIP超级会员,蓝钻用户,黄钻用户,红钻用户....我们通常的想法可能是如果数据库中存储自己会给用户存这个字段表示这个用户开通了哪些特权我们在代码中的写法可能也是如下所示:1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 type users struct { 8 name string 9 flag uint810 vip bool11 svip bool12 blue bool13 red bool14 yellow bool15 }16 17 func setVip(user users) users {18 user.vip = true19 return user20 }21 22 func isVip(user users) {23 if user.vip {24 fmt.Println("user is vip")25 } else {26 fmt.Println("user is not vip")27 }28 }29 30 func binaryTest() {31 var user users32 user.name = "test01"33 user.vip = true34 isVip(user)35 user.vip = false36 isVip(user)37 }38 39 func main() {40 binaryTest()41 42 }
这种实现方式也可以,但是明显我们需要为每个类型都做操作,并且如果以后又有更多的各种各样的会员和钻有需要添加新的,所以并不是最佳方法,下面我们通过位操作来实现上述的功能,代码如下:
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 type users struct { 8 name string 9 flag uint810 }11 12 // 这里通过位移的方式默认00000 从左边一次为vip,svip,blue,red,yellow13 const (14 vip = 115 svip = (1 << 1)16 blue = (1 << 2)17 red = (1 << 3)18 yello = (1 << 4)19 )20 21 // setFlag 用于设置用户开通了哪些特权22 func setFlag(user users, isSet bool, typeFlag uint8) users {23 if isSet == true {24 user.flag = user.flag | typeFlag25 } else {26 user.flag = user.flag ^ typeFlag27 }28 return user29 }30 31 //isFlag 用于判断用户是否开通某项特权32 func isFlag(user users, typeFlag uint8) bool {33 result := user.flag & typeFlag34 return result == typeFlag35 }36 37 func binaryTest() {38 var user users39 user.name = "coder"40 user.flag = 041 42 //判断用户是否是vip43 result := isFlag(user, vip)44 fmt.Printf("user is Vip:%t\n", result)45 46 //给用户开通vip,并看用户是否开通vip47 user = setFlag(user, true, vip)48 result = isFlag(user, vip)49 fmt.Printf("user is Vip:%t\n", result)50 51 //取消用户的vip,并查看用户是否还是vip52 user = setFlag(user, false, vip)53 result = isFlag(user, vip)54 fmt.Printf("user is Vip:%t\n", result)55 }56 57 func main() {58 binaryTest()59 }
上面代码就是一种位运算一种非常巧妙的用法,当新添加各种特权的时候只需要在最开始定义的常亮那里添加一行代码即可,就可以直接实现对这种特权的设置和取消,以及查看是否开通。
所有的努力都值得期许,每一份梦想都应该灌溉!转载地址:http://lysxa.baihongyu.com/