Go version

go version go1.22.3 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/ro0p/.cache/go-build'
GOENV='/home/ro0p/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/ro0p/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/ro0p/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go-1.22'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go-1.22/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.3'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1987530592=/tmp/go-build -gno-record-gcc-switches'

What did you do?

In a const block iota does not start from zero, it start from it's line position of the block.

const (
    A0 = iota
    A1
    A2
)

const (
    BZ = 0
    B0 = iota
    B1
    B2
)

const (
    CZ = 0
    CX = 100
    C0 = iota
    C1
    C2
)

func main() {
    fmt.Println(A0, A1, A2)
    fmt.Println(B0, B1, B2, BZ)
    fmt.Println(C0, C1, C2, CZ, CX)
}

Its very annoying especially when define flags like this:

type FlagType int
const (
    FlagNone FlagType = 0
    FlagOne FlagType = 1 << iota    // 2
    FlagTwo             // 4
    FlagThree           // 8
)

This way the flags are shifted and first bit is unused, this can leads unexpected behavior

What did you see happen?

The result of the above code is:

0 1 2 1 2 3 0 2 3 4 0 100

What did you expect to see?

Expected result is:

0 1 2 0 1 2 0 0 1 2 0 100

Comment From: seankhliao

https://go.dev/ref/spec#Iota

Its value is the index of the respective ConstSpec in that constant declaration, starting at zero.

this is working as intended.

Comment From: ro0p

Its clear, thank you.

Several IDEs show in-place help from https://pkg.go.dev/builtin#iota

iota is a predeclared identifier representing the untyped integer ordinal number of the current const specification in a (usually parenthesized) const declaration. It is zero-indexed.

This can be misunderstood

Comment From: ianlancetaylor

Do you have a suggestion for how we should rewrite it? Thanks.

Comment From: ro0p

I think https://go.dev/ref/spec#Iota is clear

Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants. Its value is the index of the respective ConstSpec in that constant declaration, starting at zero.

Thanks

Comment From: ianlancetaylor

I agree, but I also think that https://pkg.go.dev/builtin#iota is clear. And the spec refers to concepts like ConstSpec that make sense in the spec but don't necessarily make sense in the builtin package docs.

Comment From: ro0p

I can accept. I have learned it for life :) Thanks