Effective Go, and a number of other wikis and sites, exhort the Go programmer to use simple names for packages, and avoid something too general as 'misc' or 'utils'.
Additionally, Go eschews multilevel namespaces--it has one level--the package name.
So, package names are simple, one or two words combined at most, and specific to the topic.
And then there's no way to inject new code into an existing package, so what's in 'os' for example is essentially sealed by the author of whatever version of package 'os' I happen to choose to use (very likely the Go os
package).
But this is where I'm left scratching my head.
How do I write a good library of my own that extends existing concepts/packages such as os
or fmt
or something as generic as "extends map types" into a package or set of packages to share amongst my own projects (or my organization, or maybe publicly in time)?
As one arbitrary example, let's say I commonly need a function such as GetEnvOrDefault(key, def string) string
This is useful. It could be written long-hand as set of if statements, but is self-documenting and a little shorter to write once, and allows client code to consume and be a little shorter and more concise in their meaning (less visual parsing for 'GetEnvOrDefault' vs. the spelled out code over and over and over again - in this case:
// GetEnvOrDefault returns the specified environment variable's contents, or the specified default value if that env var is not present
func GetEnvOrDefault(key, defvalue string) string {
value := os.Getenv(key)
if len(value) == 0 {
value = defvalue
}
return value
}
This is just one example. It's short so as to fit here and be easy to discuss. I am going to go out on a limb and assume you can think of an arbitrary, more complex example where there is no question that you'd want to put it in a library so as to write and debug it once, then have multiple projects use and consume such functionality.
What to name this package?
Not 'utils' nor 'misc' as that's too gosh in Go. Can't be 'os' as that's effectively sealed. Can't be 'organization/os' as we can't do multi-level namespaces. Shouldn't be 'organization_os' as that isn't idiomatic for Go.
So where does that leave us?
'osx' - erm... 'osex' - fun but... 'osmisc' - seems ugly / bad... 'env' - okay, sure, but that's super generic - how much do I want to bet there are already packages more deserving of this name which would be in conflict in the future...
do you feel me?
This is one example. But I've got useful extensions to JSON, to uuid, to maps, to 32bit math, to http servers, to http clients, ...
What does a programmer do?
Copy such little misc. utility functions and types around to every project?
Come up with very non-idiomatic names for packages?
What suggestions might you have to offer?
There are several ways to deal with this.
First, even though it is discoureged, misc
, helpers
, api
packages exist in many projects.
If you are writing extensions to an existing package something
, you can name the new package somethingext
.
You can use multi-level naming by relying on your users to alias is properly:
import (
"os"
osutils "github.com/someproject/os"
)
If you are writing a replacement for an existing package something
, you can name your package something
, similar to github.com/sirupsen/logrus
, which is a replacement for stdlib log
package.