So I'm trying to test a function against every possible byte, that is 0
to 255
possibilities. How do I iterate over all possible bytes? i've
I've tried
for i := 0; i < 256; i++ {
fmt.Println(byte(i)) // prints a number 0-255
fmt.Println(byte{i}) // crashes
}
If you need to ensure that "i" variable is a byte (i.e. uint8), then you can do:
for i := byte(0); i < 255; i++ {
fmt.Println(i)
}
To me it looks like fmt.Println(byte(i))
is working. What output were you expecting?
A tricky part about looping over uint8(aka 'byte') values is that adding 1 to 255 takes you back to zero. It is easy to accidentally form an infinite loop if your for-loop condition is i <= 255
. If the goal is to iterate over every possible byte, [0-255], without introducing an indexer of a larger type, you can do it, but must be careful.
A for loop in go has three optional parts. It's a template or shorthand for manually specifying initialization, break condition and increment/decrements. (I use these names loosely b/c you can execute whatever kind of statements/expressions you want, or none at all)
I am going to write some broken code that loops forever, then rewrite it in a more explicit way:
original broken:
for i := byte(0); i <= 255; i++ {
fmt.Println(i)
}
is similar to this explicit broken version:
i := byte(0)
for ; ; {
if i <= 255{
fmt.Println(i)
i++
} else {
break
}
}
Looking at the second example, we can more easily see the problem. We want to break out of the loop when i==255
, but only after running fmt.Println(i)
-- and we definitely don't want to increment when i == 255
. There is nothing sacred about the order in which for loops check conditions and increment -- if the default order is not suited for our case, rewrite the code explicitly in an order that works. In our case, we are mostly concerned with when to break out of the loop:
a properly functioning example:
i := byte(0)
for ; ; {
fmt.Println(i)
if i == 255{
break
} else {
i++
}
}
A more concise functioning example:
for i := byte(0); ;i++ {
fmt.Println(i)
if i == 255{
break
}
}
While we are here, I will point out that for loops are abstractions surrounding conditional jump statements, or in otherwords -- gotos. In this case, I think there might be some instructional value in seeing how it would work with an explicit jump/goto:
i := byte(0)
printI:
fmt.Println(i)
if i < 255 {
i++
goto printI
}
Alternatively, if you'd like to preserve the traditional for-loop syntax for readability --
for i := 0; i < 256; i++ {
fmt.Println(byte(i))
}
Go Playground: https://play.golang.org/p/jjjg9YgXSjc