Go基礎之--位操作中你所不知道的用法
阿新 • • 發佈:2017-12-05
turn 自己 use 應用 const 代碼 只需要 寫法 直接
之前一直忽略的就是所有語言中關於位操作,覺得用處並不多,可能用到也非常簡單的用法,但是其實一直忽略的是它們的用處還是非常大的,下面先回顧一下位操作符的基礎
位操作符
與操作:&
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
或操作:!
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 & 0 = 0
異或:^
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
左移:<<
1 << 10 = 1024
1 << 20 = 1M
1 << 30 = 1G
右移:>>
1024 >> 10 = 1
1024 >>1 = 512
1024 >>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 uint8 10 vip bool11 svip bool 12 blue bool 13 red bool 14 yellow bool 15 } 16 17 func setVip(user users) users { 18 user.vip = true 19 return user 20 } 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 users 32 user.name = "test01" 33 user.vip = true 34 isVip(user) 35 user.vip = false 36 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 uint8 10 } 11 12 // 這裏通過位移的方式默認00000 從左邊一次為vip,svip,blue,red,yellow 13 const ( 14 vip = 1 15 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 | typeFlag 25 } else { 26 user.flag = user.flag ^ typeFlag 27 } 28 return user 29 } 30 31 //isFlag 用於判斷用戶是否開通某項特權 32 func isFlag(user users, typeFlag uint8) bool { 33 result := user.flag & typeFlag 34 return result == typeFlag 35 } 36 37 func binaryTest() { 38 var user users 39 user.name = "coder" 40 user.flag = 0 41 42 //判斷用戶是否是vip 43 result := isFlag(user, vip) 44 fmt.Printf("user is Vip:%t\n", result) 45 46 //給用戶開通vip,並看用戶是否開通vip 47 user = setFlag(user, true, vip) 48 result = isFlag(user, vip) 49 fmt.Printf("user is Vip:%t\n", result) 50 51 //取消用戶的vip,並查看用戶是否還是vip 52 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 }
上面代碼就是一種位運算一種非常巧妙的用法,當新添加各種特權的時候只需要在最開始定義的常亮那裏添加一行代碼即可,就可以直接實現對這種特權的設置和取消,以及查看是否開通。
Go基礎之--位操作中你所不知道的用法