Skip to content

Constants

The value of constants in Go cannot be changed at runtime. Once assigned, it cannot be modified. Its value can only come from:

  • Literals
  • Other constant identifiers
  • Constant expressions
  • Type conversions that result in constants
  • iota

Constants can only be basic data types and cannot be:

  • Other types besides basic types, such as structs, interfaces, slices, arrays, etc.
  • Function return values

The value of constants cannot be modified, otherwise it won't compile.

Initialization

Constants are declared using the const keyword. A constant must be initialized with a value when declared, and the type of the constant can be omitted.

go
const name string = "Jack" // Literal

const msg = "hello world" // Literal

const num = 1 // Literal

const numExpression = (1+2+3) / 2 % 100 + num // Constant expression

If you only declare without assigning a value, it won't compile:

go
const name string

The compiler will report an error:

missing init expr for name

Batch declaration of constants can use () to improve readability. Multiple () can be used to achieve grouping.

go
const (
   Count = 1
   Name  = "Jack"
)

const (
   Size = 16
   Len  = 25
)

In the same constant group, constants after an assigned constant don't need to be assigned. Their value defaults to the previous value:

go
const (
  A = 1
  B // 1
  C // 1
  D // 1
  E // 1
)

iota

iota is a built-in constant identifier, usually used to represent an untyped integer ordinal in a constant declaration. It is generally used within parentheses.

go
const iota = 0

Let's look at some usage cases:

go
const (
   Num = iota // 0
   Num1 // 1
   Num2 // 2
   Num3 // 3
   Num4 // 4
)

Can also be written like this:

go
const (
   Num = iota*2 // 0
   Num1 // 2
   Num2 // 4
   Num3 // 6
   Num4 // 8
)

Or:

go
const (
   Num = iota << 2*3 + 1 // 1
   Num1 // 13
   Num2 // 25
   Num3 = iota // 3
   Num4 // 4
)

From the examples above, we can see that iota is incremental. The first constant using iota is assigned an expression, and based on the ordinal value changes, it will automatically assign values to subsequent constants until a new const resets it. This ordinal is actually the relative line number of the code, relative to the first line of the current group.

go
const (
  Num  = iota<<2*3 + 1 // 1 First line
  Num2 = iota<<2*3 + 1 // 13 Second line
  _ // 25 Third line
  Num3 //37 Fourth line
  Num4 = iota // 4 Fifth line
  _ // 5 Sixth line
  Num5 // 6 Seventh line
)

The example uses the anonymous identifier _ to occupy a line. You can see that the value of iota is essentially the difference between the line where iota is located and the first line of the current const group. Different const groups don't affect each other.

Enums

Go doesn't have a separate data type for enums, unlike other languages which usually have an enum. Generally in Go, enums are implemented through custom types + const + iota. Here is a simple example:

go
type Season uint8

const (
  Spring Season = iota
  Summer
  Autumn
  Winter
)

These enums are actually numbers. Go also doesn't support direct conversion to strings, but we can add methods to custom types to return their string representation by implementing the Stringer interface.

go
func (s Season) String() string {
  switch s {
  case Spring:
    return "spring"
  case Summer:
    return "summer"
  case Autumn:
    return "autumn"
  case Winter:
    return "winter"
  }
  return ""
}

This is a simple enum implementation. You can also use the official tool Stringer to automatically generate enums.

However, it has the following disadvantages:

  • Type unsafe, because Season is a custom type, other numbers can be forcibly converted to this type

    go
    Season(6)
  • Tedious, string representation needs to be implemented manually

  • Weak expressiveness, because const only supports basic data types, these enum values can only be represented with strings and numbers

Why doesn't Go support enums at the language level is something I really don't understand. I think it would definitely be more beneficial than detrimental.

Golang by www.golangdev.cn edit