title: Multiple sets of const names with scope in Go
body: <p>I have a Go application that requires an unbounded number of sets of constants. The application also requires that I be able to map strings to (integer) consts, and vice versa at runtime. The names of the constants are guaranteed only to be valid identifiers, so it's a near certainty that there will be duplicate const names. In particular, each set of constants has an element called "Invalid". In C++11, I'd use enum classes to achieve scope. In Python, I'd probably use class variables. I'm struggling to find an idiomatic way to express this in Go. Options that I've looked at include:</p>
  
  <ul>
  <li>Using a separate package for every set of consts. This has lots of disadvantages, because I'd rather the whole set be in the same package so that I can build support for these sets at the package level, and so that I can test the whole lot without overly complicating the test code to do multi-package testing at once.</li>
  </ul>
  
  <p><code>first.go</code>:</p>
  
  <pre><code>package first
  type First int
  const (
      ConstOne First = iota
      ConstTwo
      Invalid = -1
  )
  
  func IntToCode(fi First)string { ... }
  func CodeToInt(code string)First { ... }
  </code></pre>
  
  <p><code>second.go</code>:</p>
  
  <pre><code>package second
  type Second int
  const (
      ConstOne Second = iota
      ConstTwo
      Invalid = -1
  )
  
  func IntToCode(se Second)string { ... }
  func CodeToInt(code string)Second { ... }
  </code></pre>
  
  <p><code>example.go</code>:</p>
  
  <pre><code>import (
      "first"
      "second"
  )
  
  First fi = first.CodeToInt("ConstOne")
  Second se = second.Invalid
  </code></pre>
  
  <ul>
  <li>Using the tried-and-true technique of a globally unique prefix for each const. Given, though, that the number of sets is really big, having to essentially invent and manage a bunch of namespaces using a coding convention is awkward at best. This option also forces me to modify the names of the consts (which is the whole point of using them).</li>
  </ul>
  
  <p><code>first.go</code>:</p>
  
  <pre><code>package mypackage
  
  type First int
  
  const (
      FI_CONSTONE First = iota
      FI_CONSTTWO
      FI_INVALID = -1
  )
  
  func IntToCode(fi First)string { ... }
  func CodeToInt(code string)First { ... }
  </code></pre>
  
  <p><code>second.go</code>:</p>
  
  <pre><code>package mypackage
  
  type Second int
  
  const (
      SE_CONSTONE Second = iota
      SE_CONSTTWO
      SE_INVALID = -1
  )
  
  func IntToCode(se Second)string { ... }
  func CodeToInt(code string)Second { ... }
  </code></pre>
  
  <p><code>example.go</code>:</p>
  
  <pre><code>package mypackage
  
  import (
      "first"
      "second"
  )
  
  First fi = first.CodeToInt("ConstOne")
  Second se = SE_INVALID
  </code></pre>
  
  <p>What's a better, more idiomatic solution? I'd love to be able to say things like:</p>
  
  <pre><code>First fi = First.Invalid
  </code></pre>
  
  <p>but I haven't been successful in coming up with an approach that allows this.</p>