At Agira, Technology Simplified, Innovation Delivered, and Empowering Business is what we are passionate about. We always strive to build solutions that boost your productivity.

,

12 Best Practices Every Golang Developer Must Follow

  • By Reddy Sai
  • July 9, 2018
  • 2045 Views
This blog is aimed to act as a practical guide of Golang to implement the Go best practices and design patterns which could help the golang developers achieve the greater results. You must have already seen in the Go Tutorial and Effective Go.
But to brief you more, planning to discuss more about the all best Go practices along with the detailed samples.

These are the Go best practices or techniques that has consistently shown results for superior those achieved great results

Use gofmt

Run gofmt on your code to automatically fix the majority of mechanical style issues. Almost all Go coders in the world uses gofmt.
gofmt will read the go program and it will show you the properly aligned output after indentation, vertical alignment and even it can re-format the comments too.

Commands and options

gofmt filename – This will print re-formatted code.
gofmt -w filename – This will reformat the code and updates the file.
gofmt -r ‘rule’ filename – Apply the rewrite rule to the source before reformatting.
gofmt /path/to/ package – This will format the whole package.

Here is a small example for gofmt

filename: demo.go

package main
          import "fmt"
 // this is demo to format code
            // with gofmt command
 var a int=10;
             var b int=15;
                            var c string= “Welcome to Agira”;
       func print(){
                   fmt.Println("Value for a,b and c is : ");
                        fmt.Println(a);
                                 fmt.Println((b));
                                         fmt.Println(c);
                         }

 
Passing a Command: $ gofmt demo.go

Output:

package main
 import "fmt"
 // this is demo to format code
 // with gofmt command
 var a int = 10
 var b int = 15
 var c string =  “Welcome to Agira”
 func print() {
        fmt.Println("Value for a,b and c is : ")
        fmt.Println(a)
        fmt.Println((b))
        fmt.Println(c)
 }

 

Avoid Nesting By Handling Errors First

Instead of giving multiple or nested conditions, We can break the condition if we ought to face error while processing and proceed further with coding.

err := request()
 if err != nil {
    // handling error
 } else {
    // normal code
 }

 

Instead you can do like this:

err := request()
 if err != nil {
  // handling error
  return // or continue, etc.
 }

 
// proceed to further
Less nesting means less cognitive load on the reader.
If the if statement has an initialization statement such as:

if x, err := f(); err != nil {
    // handling error
    return
 } else {
    // use x
 }

 
then this may require to define the short variable declaration in the code:

x, err := f()
 if err != nil {
    // handling error
    return
 }
 // use x

 

Error Strings

Error strings should not be capitalized (unless beginning with proper nouns or acronyms).
For Example:
Instead of thics command fmt.Errorf(“Something went wrong”) we can move with this fmt.Errorf(“something went wrong”)

Handling Errors

Do not discard errors using _ variables. If a function returns an error, check to make sure whether the function succeeded or not. Better, Handle the error and return it or that will rise as a panic error when any exceptional situation occurs.

Don’t use panic errors

Don’t use panic for normal error handling. In that case you can use error and multiple return values.

Avoid Repetition When Possible

suppose if you want use structures in controllers, as well as models, Create one common file and there you can create the structures.

Variable Name Declaration

Variable names in Go should be short rather than long. This is especially true for local variables with limited scope.
Prefer `c` to `lineCount`
Prefer `i` to `sliceIndex`

 

Type Switch To Handle Special Cases

Suppose if you’re not sure about what the interface{} type could be, you can use a type switch:
For Example:

func Write(v interface{}) {
   switch v.(type) {
   case string:
     s := v.(string)
     fmt.Printf("%T\n",s)
   case int:
     i := v.(int)
     fmt.Printf("%T\n",i)
   }
  }

 

Related: Message Queues in Golang Via RabbitMQ

Type Switch With The Short Variable Declaration

Declare a variable and it will have the type of each `case`:
For Example:

func Write(v interface{}) {
   switch x := v.(type) {
   case string:
     fmt.Printf("%T\n",x)
   case int:
     fmt.Printf("%T\n",x)
   }
  }

 

Important Code Goes First

If you have the importannt information like License information, build tags, package documentation then describe it earlier.
We can separate the Import statements, related groups by blank lines.
The standard library packages are in the first group.

import (
     "fmt"
     "io"
     "log"
   "golang.org/x/net/websocket"
  )

 
The rest of the code starting with the most significant types and ending
with helper function and types.

Import Dot

The import . form can be used to test the circular dependencies. And, it cannot be made part of the package being tested:

package foo_test
  import (
  "bar/testutil" // also imports "foo"
  . "foo"
  )

 
In this case, the test file cannot be in package foo because it uses bar/testutil, which imports foo. So we use the `import .` form to let the file pretend to be part of the package for even though it is not. Except for this one case, do not use `import .` in your programs. It makes the programs much harder to read because it is unclear when a name like Quux is a top-level identifier in the current package or in an imported package.

Related: How To Deploy a Golang Web Application with Docker

Document Your Code

Package name, with the associated documentation before.
// Package playground registers an HTTP handler at “/compile” that
// proxies requests to the golang.org playground service.
package playground
Exported identifiers appear in godoc, and they should be documented correctly.

// Author represents the person who wrote and/or is presenting the document.
  type Author struct {
  Elem []Elem
  }
  // TextElem returns the first text elements of the author details.
  // This is used to display the author' name, job title, and company
  // without the contact details.
  func (p *Author) TextElem() (elems []Elem) {

 

Comment Sentences

Comments documenting declarations should be full sentences, even if that seems a little redundant. This approach makes them to format well when extracted into godoc documentation. Comments should begin with the name of the thing being described and end in a period:

// Request represents a request to run a command.
  type Request struct { ...
  // Encode writes the JSON encoding of req to w.
  func Encode(w io.Writer, req *Request) { ... and so on.

 
Hope these Go best practices will help you to improve the quality of your code. We have listed out some more best practices in various technologies which can be found in our largest blog repository. For more inquires reach us at info@agiratech.com
We offer Golang development services for building world-class enterprise apps. We have expertise in building most complex software solutions using Google’s Go language. Chat with us now and hire golang developers within 72 hours.

Turn your vision to magnificent reality With
Our Web and Mobile Solutions