Sin*_*eth 2 boolean-logic bitmask go bitwise-operators
我是一般编程的初学者,所以如果我在提出这个问题时犯了一些错误,我很抱歉。
我正在遵循的教程介绍了此代码:
package main
import (
"fmt"
)
const (
isAdmin = 1 << iota
isHeadquarters
canSeeFinancials
canSeeAfrica
canSeeAsia
canSeeEurope
canSeeNorthAmerica
canSeeSouthAmerica
)
func main() {
var roles byte = isAdmin | canSeeFinancials | canSeeEurope
fmt.Printf ("%b\n", roles)
fmt.Printf ("Is Admin? %v\n", isAdmin & roles == isAdmin)
}
Run Code Online (Sandbox Code Playgroud)
教程中的人很快提到了这部分如何称为Bitmasking。
fmt.Printf ("Is Admin? %v\n", isAdmin & roles == isAdmin)
Run Code Online (Sandbox Code Playgroud)
现在,据我所知,这里发生的过程是这样的:计算机被询问isAdmin和角色是否都等于isAdmin并回答true。
但是,当我尝试这样做时:
fmt.Printf ("Is Admin? %v\n", roles == isAdmin)
Run Code Online (Sandbox Code Playgroud)
结果是false。
有人可以更详细地了解这个过程背后的整个逻辑吗?这一点让我有点困惑,我想知道为什么会这样。谢谢你。
您的所有角色常量都是特殊数字,其中二进制(2 的补码)表示只包含一个1位,所有其他位都是零,并且它们都不同(该1位在每个位中的位置不同)。这是通过将1数字向左移动并增加值 ( iota) 来实现的。
该role变量的值是通过使用按位或建造的:
var roles byte = isAdmin | canSeeFinancials | canSeeEurope
Run Code Online (Sandbox Code Playgroud)
按位或保留1位,在结果中将只有0每个操作数包含0在该位置的位。由于被 OR 运算的所有值1在不同位置包含一个位,因此role将包含与 OR 运算的不同角色一样多的位,并且在它们的特殊位置。
为了轻松理解这些位,让我们打印二进制表示:
fmt.Printf("isAdmin %08b\n", isAdmin)
fmt.Printf("canSeeFinancials %08b\n", canSeeFinancials)
fmt.Printf("canSeeEurope %08b\n", canSeeEurope)
fmt.Printf("-------------------------\n")
fmt.Printf("roles %08b\n", roles)
Run Code Online (Sandbox Code Playgroud)
这将输出:
isAdmin 00000001
canSeeFinancials 00000100
canSeeEurope 00100000
-------------------------
roles 00100101
Run Code Online (Sandbox Code Playgroud)
如您所见,rolescontains 1s 其中任何上述位模式具有1.
当您使用按位与(掩码)时,结果位将是0任何输入位0位于给定位置,并且1仅当两个位都是1s时才为结果位。
表达方式:
isAdmin & roles
Run Code Online (Sandbox Code Playgroud)
由于isAdmin包含单个1位,上述掩蔽将是一个数字,也可含有一个单一的1至多位,仅当roles具有一个1位在该位置。该掩码有效地表明是否roles包含该isAdmin位。如果它包含它,结果将是一个等于 的值isAdmin。如果不是,结果将是一个包含所有0位的数字,即:十进制0。
再次可视化这些位:
fmt.Printf("roles %08b\n", roles)
fmt.Printf("isAdmin %08b\n", isAdmin)
fmt.Printf("-------------------------\n")
fmt.Printf("isAdmin & roles %08b\n", isAdmin&roles)
Run Code Online (Sandbox Code Playgroud)
输出:
roles 00100101
isAdmin 00000001
-------------------------
isAdmin & roles 00000001
Run Code Online (Sandbox Code Playgroud)
试试Go Playground上的例子。
所以表达式:
isAdmin & roles == isAdmin
Run Code Online (Sandbox Code Playgroud)
会true如果roles包含(包括)的isAdmin作用,false否则。
无遮罩:
roles == isAdmin
Run Code Online (Sandbox Code Playgroud)
这将是trueifroles等于isAdmin,也就是说,如果它只包含isAdmin角色而不包含其他任何内容。如果它包含其他角色,它显然不会等于isAdmin.