Reputation: 2204
I am reading a piece of code like this (taken from fsnotify):
type Op uint32
const (
Create Op = 1 << iota
Write
Remove
Rename
Chmod
)
...
func (op Op) String() string {
var buffer bytes.Buffer
if op&Create == Create {
buffer.WriteString("|CREATE")
}
if op&Remove == Remove {
buffer.WriteString("|REMOVE")
}
if op&Write == Write {
buffer.WriteString("|WRITE")
}
if op&Rename == Rename {
buffer.WriteString("|RENAME")
}
if op&Chmod == Chmod {
buffer.WriteString("|CHMOD")
}
if buffer.Len() == 0 {
return ""
}
return buffer.String()[1:]
}
My newbie question is why someone would use a bitwise AND operation like op&Remove == Remove
to actually make a comparison.
Why not just compare the op and (Create|Remove|...) values?
Upvotes: 0
Views: 1500
Reputation: 161
This is an example of bit masking. What they're doing is defining a series of masks (Create, Remove, Write) that are integers 1,2,4,8,16,32,etc. You pass in a single op value, which can have multiple operations, and it figures out which operation to perform based on which bit is flipped. This makes more sense if you think about these numbers in a bitwise pattern. 4 == 00000100, the value for Remove. If you pass in an op code of say, 6, when you compare 00000110 && 00000100 == 00000100 you get true, because the bit that is specific to Remove, the third least significant bit, is 1.
In a less jargony and specific way, this is basically a way to pass in multiple opcodes with one byte. The reason they're doing a bitwise AND and then comparing is because it allows them to check if that specific bit is flipped, while ignoring the rest of the bits.
Upvotes: 6