11

Is there a good way to disambiguate between a package name and a local variable? I'd rather not refactor the import name or variable name if I don't have to. Take for example...

import "path"

func foo() {
    path := "/some/path"
    // Disambiguate here
    path.Join(path, "/some/other/path")
}
Lander
  • 3,369
  • 2
  • 37
  • 53
  • Jeopardy! [What is namespace pollution?](https://stackoverflow.com/q/22903542/86967) – Brent Bradburn Feb 20 '19 at 04:21
  • Does this answer your question? [How does one use a variable name with the same name as a package in Go?](https://stackoverflow.com/questions/7772229/how-does-one-use-a-variable-name-with-the-same-name-as-a-package-in-go) – kravemir Nov 08 '20 at 16:01
  • @kravemir This question was answered 7 years ago. – Lander Nov 14 '20 at 23:15

2 Answers2

10

The local variable always overrides (shadows) the package here. Pick another variable name, or alias the package as something else:

http://play.golang.org/p/9ZaJa5Joca

or

http://play.golang.org/p/U6hvtQU8dx

See nemo's alternatives in the other answer. I think the most maintainable way is to pick a variable name that won't overlap with the package name.

Eve Freeman
  • 32,467
  • 4
  • 86
  • 101
6

There are two additional options I can think of:

  1. store path.Join in a variable
  2. make path a type that implements Join

The first is simple. Instead of path.Join you store path.Join in a variable before declaring path and call it instead (play):

join := path.Join

path := "/some/path"
path = join("/some/other/path")

The second is a bit more complicated and I don't think you should actually do that but it is a possibility (play):

type Path string

func (p Path) Join(elem ...string) string {
    return path.Join(append([]string{string(p)}, elem...)...)
}

fmt.Println("Hello, playground")

path := "/some/path"

path = Path(path).Join("/some/other/path")
nemo
  • 55,207
  • 13
  • 135
  • 135