Skip to content

Instantly share code, notes, and snippets.

@jgroeneveld
Created April 30, 2015 10:21
Show Gist options
  • Save jgroeneveld/d5840560f56d66b63267 to your computer and use it in GitHub Desktop.
Save jgroeneveld/d5840560f56d66b63267 to your computer and use it in GitHub Desktop.
- Read and understand Effective Go https://golang.org/doc/effective_go.html
code structure and look
=======================
- use rules from effective go
- always use gofmt/goimports to format code
- write code for the reader, a file should "tell a story"
- important and public code goes first
- functions that belong together (all Select*, Insert*.... functions) should be in the same place
- use the shortest name that is self explanatory
- dont forget the package name will be used as identifer, too. (json.Encoder vs json.JSONEncoder).
- The length of the identifier should relate to the scope its used in.
- always think about access levels (private/public). they tell the reader what is meant to be used from the outside.
- avoid very long files, unless the contents are trivial / doing very much the same thing (like a collection of routes)
- dont try to be to clever, avoid magic, be explicit
- write self-documenting code
- http://programmers.stackexchange.com/questions/51307/self-documenting-code-vs-commented-code
- comment _why_ the code is doing something, not _what_ it is doing.
- avoid comments when "extract function" is better suited to explain functionality.
- "dont make me think"
- dont think like in java, there is no inheritance. use structural and functional composition.
- when returning multiple values from functions, name them when its not clear which value contains what.
- do not use implicit returns
errors
======
- always handle errors explicitly
- if it does not matter, ignore errors explicitly (fh, _ = os.Open(..))
- be aware that `defer fh.Close()` silently ignores the error
- when there is too much error handling, having a function/structure that operates until an error occures and ignores all other calls works fine. the error can be checked afterwards.
- example: Scanner http://play.golang.org/p/_Nar8-uBDs
- http://blog.golang.org/errors-are-values
- using panics is fine but your own panics may not leave package boundaries.
- http://blog.golang.org/defer-panic-and-recover
- example: the json package uses panics when parsing errors occur but catches them at the package boundaries and converts to errors.
- http://golang.org/src/encoding/json/decode.go#L131
interfaces
==========
- try to use the stdlibs interfaces when possible. go's implicit interfaces make that very easy.
- use an interface as narrow as possible. (Interface segregation principle)
- avoid dependencies with interfaces, this makes testing easier as well.
- the user should define the interface used (~dependency inversion).
Misc
====
- init functions
- avoid when possible
- have a init.go file per package and only one init functions per package
- be aware of call order for globals and init functions
- use the go build ./.. && go vet ./... && go test ./... toolchain (go generate first when needed)
- evaluate github.com/kisielk/errcheck
- try to avoid state.
- dont try to be to clever, avoid magic, be explicit.
- dont use reflect unless you have to
- do not optimize to early. parallelize only when really needed.
references
==========
https://golang.org/doc/effective_go.html
https://talks.golang.org/2013/bestpractices.slide#7
http://blog.golang.org/errors-are-values
http://blog.golang.org/defer-panic-and-recover
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment