Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to avoid shadowing builtins? #164

Open
abought opened this issue Feb 24, 2022 · 1 comment
Open

How to avoid shadowing builtins? #164

abought opened this issue Feb 24, 2022 · 1 comment

Comments

@abought
Copy link

abought commented Feb 24, 2022

While attempting to follow this layout new to Go, I created a file named cmd/api/main.go.

This lead to some quite unexpected behavior: go build -a -v cmd/api/ produced a working binary that did nothing (and ignored my main method). I got the expected result by changing the build command to reference either of ./cmd/api or cmd/api/main.go

After doing some digging, it was suggested that I had accidentally referenced a (quasi-hidden?) standard package with a similar name: https://pkg.go.dev/cmd/api Hence, I was getting a "binary" that successfully built, but not for my code.

I hadn't expected that the standard project layout would choose a folder (cmd) that might allow collisions with stdlib/ existing packages. Perhaps this guide could be extended with advice on how to avoid (or detect) when this is happening?

(I recognize that it's hard to be future proof, but this bit me in real usage on Day 1, while experimenting with Go on a boilerplate project with a friend)

@quasilyte
Copy link

quasilyte commented Apr 14, 2023

A few solutions to your problem:

  1. Specify a relative package file for the go command: ./cmd/api/ *
  2. Use a fully qualified path like github.com/a/b/cmd/api/

This is not exactly a golang-standards issue, since if you call your package strings you would have the same issue. It's just the way go resolves packages. Builtin packages have precedence over anything else. And while sometimes you may get lucky without (1) or (2), it can stop working if Go adds some new package. To avoid that, just be explicit: show the exact thing you want to build or run and you're golden.

(*) Note that this is not the same as relative or "dot" imports. The relative/dot imports are bad, don't use them. This is just a convention adopted by most Go tools to resolve the packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants