- Prefer stupid and simple over abstract and extendable.
- Prefer a bit of duplication over complex abstractions.
- Prefer clarity over brevity in variable, function and type names.
- Minimize usage of interfaces, generics, embedding.
- Prefer few classes over many.
- Prefer no classes over few.
- Prefer data classes over regular classes.
- Prefer functions over methods.
- Prefer public fields over getters/setters.
- Keep everything private/internal as much as possible.
- Validate early, validate a lot.
- Keep APIs stupid and minimal.
- Avoid global state.
- Prefer simplicity over micro-optimizations.
- For complex things use libraries instead of reinventing the wheel.
- Document only non-obvious public APIs or complex/weird code.
- All arguments of a public function are required: passing nil not allowed.
- Optional arguments of a public function are provided via
<MyFunctionName>Optionsas the last argument. - Avoid functional options pattern.
- Use guard clauses and early returns/continues to keep the happy path unindented.
- Use
samber/lohelpers (if nothing similar in the standard lib):lo.Filter,lo.Find,lo.Map,lo.Contains,lo.Ternary,lo.ToPtr,lo.Must, etc.
- Constructors are optional.
- Should be named
New<TypeName>[...], e.g.NewResource()andNewResourceFromManifest(). - No network/filesystem calls or resource-intensive operations. Do it somewhere higher, like in
BuildResources().
- Always add a compile-time check for each implementation, e.g.
var _ Animal = (*Dog)(nil).
- Avoid
iota. - Prefix the enum-like constant name with the type name, e.g.
LogLevelDebug LogLevel = "debug".
- Always wrap errors with additional context using
fmt.Errorf("...: %w", err). - On programmer errors prefer panics, e.g. on an unexpected case in a switch.
- Do one-line
if err := myfunc(); err != nilwherever possible, generally prefer one-line handling. - When wrapping errors with fmt.Errorf, describe what is being done, not what failed, e.g.
fmt.Errorf("read config file: %w", err)instead offmt.Errorf("cannot read config file: %w", err).
Follow these two guides: