Go基础之–位操作中你所不知道的用法

2017-12-02 分类:Go 阅读(666) 评论(0)

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

位操作符

与操作:&
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超级会员,蓝钻用户,黄钻用户,红钻用户....
我们通常的想法可能是如果数据库中存储自己会给用户存这个字段表示这个用户开通了哪些特权
我们在代码中的写法可能也是如下所示:

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()

}

这种实现方式也可以,但是明显我们需要为每个类型都做操作,并且如果以后又有更多的各种各样的会员和钻有需要添加新的,所以并不是最佳方法,下面我们通过位操作来实现上述的功能,代码如下:

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()
}

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

标签:

您可能也喜欢:

Go基础之–操作Mysql(三)

事务是数据库的一个非常重要的特性,尤其对于银行,支付系统,等等。database/sql提供了事务处理的功能。通过Tx对象实现。db.Begin会创建tx对象,后者的Exec和Query执行事务的数据库操作,最后在tx的Commit和Rollback中完成数据库事务的提交和回滚,同时释放连接。 tx...

more

Go基础之–操作Mysql(一)

关于标准库database/sql database/sql是golang的标准库之一,它提供了一系列接口方法,用于访问关系数据库。它并不会提供数据库特有的方法,那些特有的方法交给数据库驱动去实现。 database/sql库提供了一些type。这些类型对掌握它的用法非常重要。 DB数据库对象。 s...

more

Go基础之–排序和查找操作

排序操作主要都在sort包中,导入就可以使用了import("sort") 常用的操作 sort.Ints:对整数进行排序sort.Strings:对字符串进行排序sort.Float64s:对浮点数进行排序 使用例子: package main import&n...

more

评论&留言
欢迎新朋友你的到来!
还没有人抢沙发呢~
昵称
邮箱
网站

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

切换登录

注册