英文:
Iterate through all possible bytes
问题
所以我正在尝试针对每个可能的字节(即从0
到255
的可能性)测试一个函数。如何迭代所有可能的字节?我尝试过以下代码:
for i := 0; i < 256; i++ {
fmt.Println(byte(i)) // 打印数字0-255
fmt.Println(byte{i}) // 引发错误
}
英文:
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
}
答案1
得分: 2
循环遍历uint8(也称为'byte')值的一个棘手之处在于将255加1会回到零。如果你的for循环条件是i <= 255
,很容易意外形成一个无限循环。如果目标是迭代每个可能的字节[0-255],而不引入更大类型的索引器,你可以做到,但必须小心。
Go语言中的for循环有三个可选部分。它是手动指定初始化、中断条件和增量/减量的模板或简写形式。(我使用这些名称比较宽松,因为你可以执行任何类型的语句/表达式,或者根本不执行)
我将编写一些错误的代码,它会无限循环,然后以更明确的方式重写它:
原始错误的代码:
for i := byte(0); i <= 255; i++ {
fmt.Println(i)
}
类似于这个明确的错误版本:
i := byte(0)
for ; ; {
if i <= 255{
fmt.Println(i)
i++
} else {
break
}
}
从第二个示例中,我们可以更容易地看出问题所在。我们希望在i==255
时跳出循环,但是在运行fmt.Println(i)
之后--而且我们绝对不希望在i==255
时递增。for循环检查条件和递增的顺序没有什么特殊的--如果默认顺序不适合我们的情况,可以以适合的顺序明确地重写代码。在我们的情况下,我们主要关注何时跳出循环:
一个正常工作的示例:
i := byte(0)
for ; ; {
fmt.Println(i)
if i == 255{
break
} else {
i++
}
}
一个更简洁的正常工作示例:
for i := byte(0); ;i++ {
fmt.Println(i)
if i == 255{
break
}
}
顺便提一下,for循环是围绕条件跳转语句(或者换句话说--跳转语句)的抽象。在这种情况下,我认为通过使用显式的跳转/goto语句来展示它的工作原理可能有一些教育价值:
i := byte(0)
printI:
fmt.Println(i)
if i < 255 {
i++
goto printI
}
英文:
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
}
答案2
得分: 0
另外,如果您希望保留传统的for循环语法以提高可读性,可以使用以下代码:
for i := 0; i < 256; i++ {
fmt.Println(byte(i))
}
Go Playground链接:https://play.golang.org/p/jjjg9YgXSjc
英文:
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
答案3
得分: -2
对我来说,fmt.Println(byte(i))
看起来是有效的。你期望得到什么输出?
英文:
To me it looks like fmt.Println(byte(i))
is working. What output were you expecting?
答案4
得分: -3
如果你需要确保变量"i"是一个字节(即uint8),那么你可以这样做:
for i := byte(0); i < 255; i++ {
fmt.Println(i)
}
英文:
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论