Elegant constants in the Iota:golang

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Note: The author of this article is Katrina Owen, the original address is iota:elegant Constants in Golang

Some concepts have names, and sometimes we focus on those names, even (especially) in our code.

const (    CCVisa            = "Visa"    CCMasterCard      = "MasterCard"    CCAmericanExpress = "American Express")

At other times, we just focus on being able to differentiate one thing from the other. Sometimes, there are times when something has no intrinsic meaning. For example, we store products in a database table, and we may not want to store their classifications as strings. We are not concerned about how this classification is named, moreover, the name has been changing in the market.

We are only concerned with how they are differentiated from each other.

const (    CategoryBooks    = 0    CategoryHealth   = 1    CategoryClothing = 2)

Using 0, 1, and 2 instead, we can also choose 17, 43, and 61. These values are arbitrary.

Constants are important, but they are difficult to infer and difficult to maintain. In some languages like Ruby developers usually just avoid them. In Go, constants have many subtleties. When used well, it makes the code very elegant and easy to maintain.

Self-growth

In Golang, a handy idiom is the use of identifiers iota , which simplifies the definition of constants for growth numbers, giving the same values to the exact classification.

const (    CategoryBooks = iota // 0    CategoryHealth       // 1    CategoryClothing     // 2)

Custom Types

Self-growing constants often contain a custom type that allows you to rely on the compiler.

type Stereotype intconst (    TypicalNoob Stereotype = iota // 0    TypicalHipster                // 1    TypicalUnixWizard             // 2    TypicalStartupFounder         // 3)

If a function takes int its arguments instead of Stereotype , if you pass one to it Stereotype , it will have problems during the compiler period.

func CountAllTheThings(i int) string {                return fmt.Sprintf("there are %d things", i)}func main() {    n := TypicalHipster    fmt.Println(CountAllTheThings(n))}// output:// cannot use TypicalHipster (type Stereotype) as type int in argument to CountAllTheThings

The opposite is also true. Given a function Stereotype as an argument, you can't pass it on int .

func SoSayethThe(character Stereotype) string {    var s string    switch character {    case TypicalNoob:        s = "I'm a confused ninja rockstar."    case TypicalHipster:        s = "Everything was better we programmed uphill and barefoot in the snow on the SUTX 5918"    case TypicalUnixWizard:        s = "sudo grep awk sed %!#?!!1!"    case TypicalStartupFounder:        s = "exploit compelling convergence to syndicate geo-targeted solutions"    }    return s}func main() {    i := 2    fmt.Println(SoSayethThe(i))}// output:// cannot use i (type int) as type Stereotype in argument to SoSayethThe

This is a dramatic twist, albeit so. You can pass a numeric constant, and then it will work.

func main() {    fmt.Println(SoSayethThe(0))}// output:// I'm a confused ninja rockstar.

This is because constants are weakly typed in Go until it is used in a strict context.

Skipping Values

Imagine that you are dealing with consumer audio output. The audio may not have any output whatsoever, or it may be mono, stereo, or surround sound.

This may have some potential logic definitions without any output of 0, mono as 1, stereo 2, and the value is provided by the number of channels.

So what value do you give Dolby 5.1 surround stereo.

On the one hand, it has 6 channel outputs, but on the other hand, only 5 channels are full bandwidth channels (hence the 5.1 designation-which .1 represents the low-frequency effect channel).

Anyway, we don't want to add to 3 simply.

We can use the underscore to skip the unwanted values.

type AudioOutput intconst (    OutMute AudioOutput = iota // 0    OutMono                    // 1    OutStereo                  // 2    _    _    OutSurround                // 5)

An expression

iotaYou can do more, not just increment. More precisely, it is iota always used for increment, but it can be used to store the resulting value in an expression, in a constant.

Here we create a constant for the bitmask.

type Allergen intconst (    IgEggs Allergen = 1 << iota // 1 << 0 which is 00000001    IgChocolate                         // 1 << 1 which is 00000010    IgNuts                              // 1 << 2 which is 00000100    IgStrawberries                      // 1 << 3 which is 00001000    IgShellfish                         // 1 << 4 which is 00010000)

The job is because when you const have only one noon line in a group, it will use the growth to iota get the previous expression and use it again. In the Go language spec, this is known as the implicit repetition of the last non-empty expression list.

If you are allergic to eggs, chocolate and seafood, flip these bits to the "on" position (mapping bits from left to right). Then you will get a bit value 00010011 that corresponds to the decimal 19.

fmt.Println(IgEggs | IgChocolate | IgShellfish)// output:// 19

This is an example of a very good definition of the order of magnitude in effective Go:

type ByteSize float64const (    _           = iota                   // ignore first value by assigning to blank identifier    KB ByteSize = 1 << (10 * iota) // 1 << (10*1)    MB                                   // 1 << (10*2)    GB                                   // 1 << (10*3)    TB                                   // 1 << (10*4)    PB                                   // 1 << (10*5)    EB                                   // 1 << (10*6)    ZB                                   // 1 << (10*7)    YB                                   // 1 << (10*8))

Today I learned that after Zettabyte is yottabyte.

But wait, there's more.

What happens when you define two constants in a row?
What is the value of Banana? 2 or 3? What is the value of Durian?

const (    Apple, Banana = iota + 1, iota + 2    Cherimoya, Durian    Elderberry, Fig)

iotaGrows on the next line instead of immediately getting its reference.

// Apple: 1// Banana: 2// Cherimoya: 2// Durian: 3// Elderberry: 3// Fig: 4

This is messed up, because now your constants have the same value.

Therefore, the right

In Go, there are a lot of things to say about constants, and you should read Rob Pike's article on the Golang blog.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.