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


Related articles: