What do you think the following program will print?
https://gist.github.com/09755207f9bdfd13f71639d3e0f301cd
This program will print: 4
.
When you use iota
in a const
group, the values of the constants will advance according to the first operation. The <<
operator is "left shift". It moves the bits of a number to the left, basically multiplying it by power of 2.
For example, if we have the number 5, which (on byte, which is 8 bits) is 00000101
. When you write 5 << 1
all the bits are shifted one place to the left. Making it 00001010
which is 10=5*2
. When you write 5 << 2
the bits are shifted two places to the left, making it 00010100
or 20=5*4
.
The first value, Read
is 1<<0
which is 1. The next value, Write
is 1<<1
which is 2. Finally, Execute
is 1<<2
which is 4.
iota
is Go's version of enumeration, if you're coming from other language, you're probably used to enumerated types being printed as strings. In Go, you can implement that fmt.Stringer.
https://gist.github.com/9ced59bee292545c3a9bb1f571678056
One you do that, the code above will print execute
.
Note that FilePerm
can be any uint16
value, this is why we have the final clause in the String
method. Why do you think the comment says "don't use %s or %v"?
Using values that are power of 2 enables you to use bitwise operations or bitmasks. For example:
https://gist.github.com/00c3b9ca3a039a0ae0f4758605f8df13
Bitmasks are a compact way of representing flags or options. If instead of using a bitmask, you'll use a struct like:
https://gist.github.com/6b536941ad2f2b7629498264e5a7c881
Then it'll be 3 times as big:
https://gist.github.com/ff7202c64ac7254eff44f869b2cc84d8
2 byte difference might not seem a lot, but as Dave Cheney says: "A few bytes here, a few there, pretty soon you’re talking real memory."
I encourage you to try out bitmask next time you write some code, I'm sure you'll find them useful.