The use of bit manipulation in Go that you don't know about
- 2020-06-12 09:19:51
- OfStack
preface
Since the previous 1 ignores bitwise operations in all languages, it is not very useful and may be very simple to use, but what the 1 ignores is that they are very useful. Let's review the basics of the 1 bitwise operator first
An operator
With the operation:
&
1
&
1 = 1
1
&
0 = 0
0
&
1 = 0
0 & 0 = 0
Or operation:!
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 & 0 = 0
Xor: ^
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
Left:
<
<
1
<
<
10 = 1024
1
<
<
20 = 1M
1 < < 30 = 1G
Moves to the right:
>
>
1024
>
>
10 = 1
1024
>
>
1 = 512
1024 > > 2 = 256
An application example of the above knowledge
This example may not be particularly rigorous in practice, but it does provide an idea for writing code
Take the privileges of weibo or qq users as an example:
1 qq can use VIP member, SVIP super member, blue diamond user, yellow diamond user, red diamond user...
The general idea might be that if you store yourself in the database you're going to store this field for the user to indicate what privileges the user has granted
The way we write it in the code might look something like this:
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()
}
This implementation is fine, but obviously we need to do it for each type, and if more members and drills of various kinds need to be added in the future, so it is not the best method, let's implement the above function by bit operation, the code is as follows:
package main
import (
"fmt"
)
type users struct {
name string
flag uint8
}
// This is the default by displacement 00000 From the left 1 Time for vip,svip,blue,red,yellow
const (
vip = 1
svip = (1 << 1)
blue = (1 << 2)
red = (1 << 3)
yello = (1 << 4)
)
// setFlag Used to set what privileges the user has been granted
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 Used to determine whether a user has granted a privilege
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
// Determine if the user is vip
result := isFlag(user, vip)
fmt.Printf("user is Vip:%t\n", result)
// Open to users vip, And see if the user is open vip
user = setFlag(user, true, vip)
result = isFlag(user, vip)
fmt.Printf("user is Vip:%t\n", result)
// Cancel the user's vip , and see if the user is still vip
user = setFlag(user, false, vip)
result = isFlag(user, vip)
fmt.Printf("user is Vip:%t\n", result)
}
func main() {
binaryTest()
}
The above code is a very clever use of 1 bit operation. When adding various privileges, you just need to add 1 line of code in the original definition of the constant light, and you can directly implement the setting and cancellation of this privilege and see whether it is enabled or not.
Attached to the common > > Moves to the right < < Moving left feeling right moving left should also be very common use
Continue with the example:
package main
import "fmt"
func main() {
x := 2
y := 4
fmt.Println(x<<1)
fmt.Println(y>>1)
}output:4 2
I'm going to convert to base 2 and then I'm going to move left or right.
conclusion