前言
因為之前一直忽略的就是所有語言中關于位操作,覺得用處并不多,可能用到也非常簡單的用法,但是其實一直忽略的是它們的用處還是非常大的,下面先回顧一下位操作符的基礎
位操作符
與操作:&
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package main import ( "fmt" ) type users struct { name string flag uint8 vip bool svip bool blue bool red bool yellow bool } func setVip(user users) users { user.vip = true return user } func isVip(user users) { if user.vip { fmt.Println("user is vip") } else { fmt.Println("user is not vip") } } func binaryTest() { var user users user.name = "test01" user.vip = true isVip(user) user.vip = false isVip(user) } func main() { binaryTest() } |
這種實現方式也可以,但是明顯我們需要為每個類型都做操作,并且如果以后又有更多的各種各樣的會員和鉆有需要添加新的,所以并不是最佳方法,下面我們通過位操作來實現上述的功能,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
package main import ( "fmt" ) type users struct { name string flag uint8 } // 這里通過位移的方式默認00000 從左邊一次為vip,svip,blue,red,yellow const ( vip = 1 svip = (1 << 1) blue = (1 << 2) red = (1 << 3) yello = (1 << 4) ) // setFlag 用于設置用戶開通了哪些特權 func setFlag(user users, isSet bool, typeFlag uint8) users { if isSet == true { user.flag = user.flag | typeFlag } else { user.flag = user.flag ^ typeFlag } return user } //isFlag 用于判斷用戶是否開通某項特權 func isFlag(user users, typeFlag uint8) bool { result := user.flag & typeFlag return result == typeFlag } func binaryTest() { var user users user.name = "coder" user.flag = 0 //判斷用戶是否是vip result := isFlag(user, vip) fmt.Printf("user is Vip:%t\n", result) //給用戶開通vip,并看用戶是否開通vip user = setFlag(user, true, vip) result = isFlag(user, vip) fmt.Printf("user is Vip:%t\n", result) //取消用戶的vip,并查看用戶是否還是vip user = setFlag(user, false, vip) result = isFlag(user, vip) fmt.Printf("user is Vip:%t\n", result) } func main() { binaryTest() } |
上面代碼就是一種位運算一種非常巧妙的用法,當新添加各種特權的時候只需要在最開始定義的常亮那里添加一行代碼即可,就可以直接實現對這種特權的設置和取消,以及查看是否開通。
附常見的>>右移 <<左移 感覺右移左移應該也是非常常見的使用了
繼續看例子:
1
2
3
4
5
6
7
8
9
10
|
package main import "fmt" func main() { x := 2 y := 4 fmt.Println(x<<1) fmt.Println(y>>1) }output:4 2 |
進行轉化為二進制 然后向左或者向右移動。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://www.cnblogs.com/zhaof/p/7979651.html