Go - Package Guidelines
Here are some tips how to write Go packages.
Name packages according to standards.
- Use only lowercase; no spaces, no dashes, no underscores, no uppercase.
- Avoid abbreviations if they aren't common knowledge.
- Avoid common variable names like
buffer
orbuf
. - Avoid meaningless package names like
util
,common
andshared
. - Keep package names short, so no
networkinginitializators
.
// bad
package util
func NewStringSet(...string) map[string]bool {...}
func SortStringSet(map[string]bool) []string {...}
...
// good
package stringset
func New(...string) map[string]bool {...}
func Sort(map[string]bool) []string {...}
Make packages as small as possible. A package with one type and the related methods is a good scope. One compiled program/library can contain as many internal packages as you want as long as there is a single main
package, which should be at the project root. Usually, the more packages there are the better, as it forced you to divide your code to logical groups.
A single package can consist of any number of files.
# all of these are part of the `card` package, you can use import to incldue
# them all at once
card/
cardnumber.go
cardsuite.go
cardsort.go
Name package's public parts from user's point of view.
// bad
http.HttpServer
time.TimeNow()
// good
http.Server
time.Now()
jpeg.Reader, bufio.Reader, csv.Reader.
Provide sensible defaults. If possible, provide default behaviour for your Go packages so the packages is usable right after import
. The same pattern is used in multiple native packages e.g. log
, flag
and http
native Go packages.
package mylogger
import "fmt"
// Real functionality and interface.
type MyLogger struct {}
func (self *MyLogger ) Log(str string) {
fmt.Println(str)
}
// Setup for the simpler interface.
var mainMyLogger MyLogger;
func init() {
mainMyLogger = MyLogger{}
}
// Simpler interface for the default values.
func Log(str string) {
mainMyLogger.Log(str);
}
// Usage example.
package main
import mylogger
func main() {
mylogger.Log("Hello")
}