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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Spring相关

第1章—Spring之旅—简化Spring的java开发

区别于EJB的特性 简化javaBean,为了降低java开发的复杂性,Spring采取了以下4种关键策略:

662
来自专栏java学习

关于Spring面试题讲解4

面向切面的编程,或AOP,是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。

902
来自专栏别先生

Spring之注解实现aop(面向切面编程)

1:Aop(aspect object programming)面向切面编程,名词解释:     1.1:功能:让关注点代码与业务逻辑代码分离     1.2:...

23810
来自专栏JAVA高级架构

女程序员的梦,众网友的神回复

女程序员发的一条微博: “昨晚梦见男朋友和别的女人在逛街,梦里我的第一反应就是查源代码,结果调试半天查不出来为什么显示的那个女人不是我,最后含泪把那个女人注释掉...

3385
来自专栏生信技能树

把vcf文件转换为maf格式,肿瘤外显子上游分析教程到此为止

可能还有一些教程我漏掉了,毕竟这些年发布了近万篇教程了,大家直接我去我博客,生信菜鸟团就可以搜索,去我们的论坛,生信技能树里面也可以搜到。

2692
来自专栏我的小碗汤

这个坑你能填吗?

今天利用java发邮件,本地windows上测试时发送ok的,部署到服务器上却报异常,让我们走进异常,探索到底坑在哪里,并填之。

842
来自专栏battcn

一起来学SpringBoot | 第二十二篇:轻松搞定重复提交(一)

在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发...

2222
来自专栏coolblog.xyz技术专栏

Spring AOP 源码分析系列文章导读

前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解。在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈...

883
来自专栏我是攻城师

spark总体概况

3346
来自专栏面朝大海春暖花开

AOP

AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对...

802

扫码关注云+社区