3
\$\begingroup\$

I'm imagining go generate would be a good tool for this. I want to convert strings to ints to save space.

type Source int

func NewSource(s string) Source {
    switch s {
    case "Twitter":
        return Twitter
    case "Facebook":
        return Facebook
    case "Gplus":
        return Gplus
    case "Spotify":
        return Spotify
    case "Linkedin":
        return Linkedin
    case "Github":
        return Github
    case "Lastfm":
        return Lastfm
    default:
        panic(ErrUnknownSourceType)
    }
}

const (
    Twitter Source = iota
    Facebook
    Gplus
    Spotify
    Linkedin
    Github
    Lastfm
)
\$\endgroup\$
  • 2
    \$\begingroup\$ Please edit your title to include what the code does. \$\endgroup\$ – ratchet freak Aug 14 '15 at 10:26
5
\$\begingroup\$

Shortest (shortest by you) would be indeed to use go generate. If you don't want to do that:

You have to enumerate your source names and source values to associate them, you can't avoid that.

But this enumeration and pairing can be shorter by using a map[string]Source:

var srcMap = map[string]Source{
    "Twitter":  Twitter,
    "Facebook": Facebook,
    "Gplus":    Gplus,
    "Spotify":  Spotify,
    "Linkedin": Linkedin,
    "Github":   Github,
    "Lastfm":   Lastfm,
}

func NewSource(s string) Source {
    if src, ok := srcMap[s]; ok {
        return src
    }
    panic(ErrUnknownSourceType)
}

Also note that panicing is a little "strong" reaction for an invalid source name. I would rather return an error along with the source, or return a special UnknownSrc source instead of panicing.

And while we're at it: you should exploit the zero value of Source for representing UnknownSrc and that way you don't even have to use the comma-ok idiom when checking in the map: indexing a map returns the zero value of the value type if the key is not found.

So:

const (
    UnknownSrc Source = iota // It will be 0, zero value for the underlying type (int)
    Twitter
    // ... and your other sources
)

And this way converting a source name to the Source type is one-line:

func NewSource(s string) Source {
    return srcMap[s]
}

It's just indexing a map, you don't even need a function for that.

If you would want to return an error, it could look like this:

func NewSource(s string) (Source, error) {
    if src, ok := srcMap[s]; ok {
        return src, nil
    }
    return UnknownSrc, errors.New("Invalid Source name!") 
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.