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

简介: 之前一直忽略的就是所有语言中关于位操作,觉得用处并不多,可能用到也非常简单的用法,但是其实一直忽略的是它们的用处还是非常大的,下面先回顾一下位操作符的基础 位操作符 与操作:&1 & 1 = 11 & 0 = 00 & 1 = 00 & 0 = 0 或操作:!1 | 1 = 11 | 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超级会员,蓝钻用户,黄钻用户,红钻用户....
我们通常的想法可能是如果数据库中存储自己会给用户存这个字段表示这个用户开通了哪些特权
我们在代码中的写法可能也是如下所示:

 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 }

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

所有的努力都值得期许,每一份梦想都应该灌溉!
目录
相关文章
|
3月前
|
JSON 人工智能 Go
go 反射的常见用法
go 反射的常见用法
45 4
|
3月前
|
人工智能 编译器 Go
go slice 基本用法
go slice 基本用法
52 1
|
3月前
|
Go 调度 C语言
go语言中一些用法
本文详细解析了Go语言如何通过C语言扩展其功能。主要包括:使用注释书写C代码、通过Go调用C中的函数示例及背后的工作原理;解释了Go如何通过内存结构体传递参数并接收返回值,以及Go调度器如何处理C代码执行期间的控制流问题;讨论了使用cgo的优势与局限性;最后介绍了Go语言中`defer`关键字的工作机制,并通过具体示例展示了反射在动态调用函数中的应用。
|
3月前
|
Go
实验深度理解Go中try...catch...的panic、defer、recover用法
文章通过实验代码演示了Go语言中如何使用panic、defer和recover函数来模拟try...catch...的异常处理机制,并详细解释了每个函数的作用和在异常处理中的使用场景。
36 0
|
5月前
|
Unix Shell 编译器
Go 中空结构有什么用法
在 Go 语言中,空结构体 struct{} 是一个非常特殊的类型,它不包含任何字段并且不占用任何内存空间。虽然听起来似乎没什么用,但空结构体在 Go 编程中实际上有着广泛的应用。本文将详细探讨空结构体的几种典型用法,并解释为何它们在特定场景下非常有用。
|
11月前
|
Go
go import几种用法
go import几种用法
100 1
|
编译器 Go
Go语言常量完全手册 const用法看这一篇就够了
Go语言常量完全手册 const用法看这一篇就够了
856 0
|
6月前
|
存储 安全 Go
掌握Go语言:Go语言类型转换,解锁高级用法,轻松驾驭复杂数据结构(30)
掌握Go语言:Go语言类型转换,解锁高级用法,轻松驾驭复杂数据结构(30)
|
6月前
|
Go 索引
Go 语言基本类型和运算符用法
Go 语言基本类型和运算符用法
31 0
|
Go
一文吃透Go语言bool用法 不懂布尔看这里!
一文吃透Go语言bool用法 不懂布尔看这里!
922 0