Go

These are the Go language-specific coding styles. Anything mentions here overrides/adds to the "In General" guides.

#1 - Linter Checking

  • Anything did not pass gofmt and golangci-lint should not be committed to repository. Period.

The Go communities and development team had spend almost all their strength to develop such a powerful linter checking. Use them before committing the codes.

Rationale

  1. Go is a high standard programming language. Comply to their standardization and quality checking.

#2 - Comments

  • Inherit the "In General" commenting guide.
  • Follows Go commenting standards like:
/*
Package regexp implements a simple library for regular expressions.

The syntax of the regular expressions accepted is:

    regexp:
        concatenation { '|' concatenation }
    concatenation:
        { closure }
    closure:
        term [ '*' | '+' | '?' ]
    term:
        '^'
        '$'
        '.'
        character
        '[' [ '^' ] character-ranges ']'
        '(' regexp ')'
*/
package regexp

#3 - Panic vs. Error Handling

  • DO NOT panic unless it is mission critical process that is fixable upfront.
  • Use error and multi-values handling as default approach.

Rationale

  1. Comply to Go error handling convention.
  2. Use the right tool for the right problem:
    1. graceful error handling - use error approach
    2. critical issue and cannot afford any error - use panic without encouraging recovery() approach

#4 - Errors Handling

  • Keep the message lowercase.
  • Write it with context and meant for a purpose.
  • Don't explicitly handle error if there is one already available. Just return with the existing one.
  • Errors are values. Don't just process it; remember to return it.

Rationale

  1. So that the error message is allowed for concatenation since it is usually being used as such:
    • log.Printf("Reading %s: %v", filename, err).

#5 - Imports

  • No circular dependency
  • Rename the most local package in the event of naming collision.
  • Avoid import blank and import dot unless there is a valid technical reason.

Rationale

  1. Keep the import statement simple and standardized to 1 form.

#6 - Naming Convention

  • Inherit In General practices.
  • Use CamelCase convention.
  • start with small camelCase for private functions, big CamelCase for public functions and API

Rationale

  1. Keep the import statement simple and standardized to 1 form.

#7 - Function

Rationale

  1. Keep the import statement simple and standardized to 1 form.

#8 - Variables

  • Inherit In General practices.
  • Use the proper declaration/initialization convention introduced by Go.

These are the proper Go practices:

// Declare but not initialized - use var
var players int    // 0
var things []Thing // an empty slice of Things
var thing Thing    // empty Thing struct


// Declare and initialized - use :=
min, max := 0, 1000
things := nil
thing := &Thing{}


// ambiguous types, use either but clarify up with function or type
var length uint32 = 0x80
length := uint32(0x80)

Rationale

  1. Keep best practices with Go community.

#9 - Defer over Goto

  • Always use defer and defer immediately right after execute.
  • Error check the deferment. Use the following:
func main() {
        r, err := Open("a")
        if err != nil {
                log.Fatalf("error opening 'a'\n")
        }
        defer func() {
                err := r.Close()
                if err != nil {
                        log.Fatal(err)
                }
        }()

        r, err = Open("b")
        if err != nil {
                log.Fatalf("error opening 'b'\n")
        }
        defer func() {
                err := r.Close()
                if err != nil {
                        log.Fatal(err)
                }
        }()
}

Rationale

  1. Follow the standardization.

#10 - Read Up Effective Go

  • A lot of standardization is available in Effective Go's guide. Read up.

Rationale

  1. Prevent Regrets.

#11 - Packaging

  • Avoid common / All-in-one packages
  • Keep package to 1 single purpose.

Rationale

  1. When the common packages grow larger, it is hard to distribute the updates without damaging one place to another.

That's all about Go coding styles conventions.