Go custom type to implement enumeration type restriction

Time:2021-2-10

Today, I found a problem using iota. When defining the alias type, call the function to report an error. No more nonsense. Let’s take a look at an example

package main

import "fmt"

Type aliasint // define the alias of int as aliasint

const (
    AA aliasint = iota // initialize 0
    BB                 // 1
    CC                 // 2
)

func test(m Aliasint) { fmt.Println(m) }

func main() {
    m := AA
    test(m)
    x := 1
    test(x)
    // cannot use x (type int) as type Aliasint in argument to test
}

Error reporting means that x (type int) cannot be used as the type aliasint in the parameter to test

Analysis: because int is aliased. Using extra variables of the same type is not supported. Why? Because X: = 1, where x is implicitly defined as int, and int is no longer the so-called “int”, but alias int
How to understand? If we do, then no problem, continue to see:

package main

import "fmt"

//Type aliasint // define the alias of int as aliasint

const (
    AA int = iota // initialize 0
    BB                 // 1
    CC                 // 2
)

func test(m int) { fmt.Println(m) }

func main() {
    m := AA
    test(m)
    x := 1
    test(x)
}

Output:

0
1

We see normal output without aliasing. So, how to call a function to pass parameters using an alias?

package main

import "fmt"

Type aliasint // define the alias of int as aliasint

const (
    AA aliasint = iota // initialize 0
    BB                 // 1
    CC                 // 2
)

func test(m Aliasint) { fmt.Println(m) }

func main() {
    m := AA
    test(m)
    Test (110) // constants are automatically converted by the compiler
}

Output:

0
110

Conclusion: the custom type must be defined with the variable name of the alias type, because the alias type is “overridden”. Let’s look at the following code. I believe you can understand it

package main

import "fmt"

Type aliasint // define the alias of int as aliasint

const (
    AA aliasint = iota // initialize 0
    BB                 // 1
    CC                 // 2
)

func test(m Aliasint) { fmt.Println(m) }

func main() {
    m := AA
    test(m)
    var x Aliasint
    x = 99
    test(x)
}

Output:

0
99