zoukankan      html  css  js  c++  java
  • Go基础之--位操作中你所不知道的用法

    之前一直忽略的就是所有语言中关于位操作,觉得用处并不多,可能用到也非常简单的用法,但是其实一直忽略的是它们的用处还是非常大的,下面先回顾一下位操作符的基础

    位操作符

    与操作:&
    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    bool
    11     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
    ", result)
    45 
    46     //给用户开通vip,并看用户是否开通vip
    47     user = setFlag(user, true, vip)
    48     result = isFlag(user, vip)
    49     fmt.Printf("user is Vip:%t
    ", result)
    50 
    51     //取消用户的vip,并查看用户是否还是vip
    52     user = setFlag(user, false, vip)
    53     result = isFlag(user, vip)
    54     fmt.Printf("user is Vip:%t
    ", result)
    55 }
    56 
    57 func main() {
    58     binaryTest()
    59 }

    上面代码就是一种位运算一种非常巧妙的用法,当新添加各种特权的时候只需要在最开始定义的常亮那里添加一行代码即可,就可以直接实现对这种特权的设置和取消,以及查看是否开通。

  • 相关阅读:
    转:孙振耀谈人生(推荐)
    自绘按钮的实现
    数据结构知识
    Direct Show采集图像实例
    视觉跟踪
    改变对话框控件的颜色
    笔试题
    CBitmapButton的使用
    Rotor (SSCLI) 2.0 登场!
    Under the hood: 从Win32 SEH到CLI异常处理模型
  • 原文地址:https://www.cnblogs.com/zhaof/p/7979651.html
Copyright © 2011-2022 走看看