Ambiguous behavior of For loop in Golang

落爺英雄遲暮 提交于 2020-05-09 07:25:54

问题


I want make some simple loop like this:

package main

import "fmt"

func main() {
    var i uint32 // code bellow works fine with int32
    for i = 31; i >= 0; i-- {
        fmt.Println(i)
    }
}

But this loop is endless, if i has type uint32. If i is int32 it`s ok.

How I can break this loop, if i has type uint32 without checking if i == 0?


回答1:


i is of type uint32, so once it reaches 0, decrementing again will result in the max value of uint32. Change the loop condition to check for that:

var i uint32 // code bellow works fine with int32
for i = 31; i != 0xffffffff; i-- {
    fmt.Println(i)
}

Try it on the Go Playground.

Or use the math.MaxUint32 constant:

var i uint32 // code bellow works fine with int32
for i = 31; i != max.MaxUint32; i-- {
    fmt.Println(i)
}

Or use the ^uint32(0) expression, where the ^ operator is the bitwise complement operator, applied on 0 will give you a value where all the bits are ones: the max value for uint32.

Although if you look at the code, it's not intuitive, hard to understand. So you should use alternatives where this is not required and are more straightforward, such as using int32 and checking for i >= 0, or use an upward loop, such as:

for i := uint32(0); i < 32; i++ {
    fmt.Println(31 - i)
}

Or offset the loop variable's range with +1, so you can test for i >= 1 or i > 0:

for i := uint32(32); i > 0; i-- {
    fmt.Println(i-1)
}


来源:https://stackoverflow.com/questions/50831892/ambiguous-behavior-of-for-loop-in-golang

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!