Go語言中你所不知道的位操作用法
前言
因?yàn)橹耙恢焙雎缘木褪撬姓Z言中關(guān)于位操作,覺得用處并不多,可能用到也非常簡單的用法,但是其實(shí)一直忽略的是它們的用處還是非常大的,下面先回顧一下位操作符的基礎(chǔ)
位操作符
與操作:&
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
關(guān)于上述知識的一個(gè)應(yīng)用實(shí)例
可能這個(gè)例子在實(shí)際中用并不是特別嚴(yán)謹(jǐn),但是也提供了我們寫代碼的一種思路
這里拿微博或者qq用戶的特權(quán)為例子:
一個(gè)qq號可以用VIP會員,SVIP超級會員,藍(lán)鉆用戶,黃鉆用戶,紅鉆用戶....
我們通常的想法可能是如果數(shù)據(jù)庫中存儲自己會給用戶存這個(gè)字段表示這個(gè)用戶開通了哪些特權(quán)
我們在代碼中的寫法可能也是如下所示:
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()
}
這種實(shí)現(xiàn)方式也可以,但是明顯我們需要為每個(gè)類型都做操作,并且如果以后又有更多的各種各樣的會員和鉆有需要添加新的,所以并不是最佳方法,下面我們通過位操作來實(shí)現(xiàn)上述的功能,代碼如下:
package main
import (
"fmt"
)
type users struct {
name string
flag uint8
}
// 這里通過位移的方式默認(rèn)00000 從左邊一次為vip,svip,blue,red,yellow
const (
vip = 1
svip = (1 << 1)
blue = (1 << 2)
red = (1 << 3)
yello = (1 << 4)
)
// setFlag 用于設(shè)置用戶開通了哪些特權(quán)
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 用于判斷用戶是否開通某項(xiàng)特權(quán)
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()
}
上面代碼就是一種位運(yùn)算一種非常巧妙的用法,當(dāng)新添加各種特權(quán)的時(shí)候只需要在最開始定義的常亮那里添加一行代碼即可,就可以直接實(shí)現(xiàn)對這種特權(quán)的設(shè)置和取消,以及查看是否開通。
附常見的>>右移 <<左移 感覺右移左移應(yīng)該也是非常常見的使用了
繼續(xù)看例子:
package main
import "fmt"
func main() {
x := 2
y := 4
fmt.Println(x<<1)
fmt.Println(y>>1)
}output:4 2
進(jìn)行轉(zhuǎn)化為二進(jìn)制 然后向左或者向右移動。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
golang 如何用反射reflect操作結(jié)構(gòu)體
這篇文章主要介紹了golang 用反射reflect操作結(jié)構(gòu)體的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
golang中struct和interface的基礎(chǔ)使用教程
Go不同于一般的面向?qū)ο笳Z言,需要我們好好的學(xué)習(xí)研究,下面這篇文章主要給大家介紹了關(guān)于golang中struct和interface的基礎(chǔ)使用的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03
golang?Gin上傳文件返回前端及中間件實(shí)現(xiàn)示例
這篇文章主要為大家介紹了golang?Gin上傳文件返回前端及中間件實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04

