Go Cheat Sheet: Your Quick Reference for Golang Essentials

Your ultimate quick reference for Go programming! This cheat sheet covers essential syntax, commands, and best practices to help you code efficiently.

Getting Started

hello.go

package main

import "fmt"

func main() {
    fmt.Println("Hello, world!")
}

#Run directly

$ go run hello.go
Hello, world!

See: Or try it out in the Go repl

Variables

// Declaring variables using `var`
var message string
message = "Learn Go!"

// Declaring multiple variables with initial values
var x, y int = 1, 2
var isActive bool = true

// Short variable declaration
message := "Learn Go!"   // string
x, y := 1, 2             // int
isActive := true         // bool

Functions

package main

import "fmt"

// Program entry point
func main() {
    fmt.Println("Welcome to Go!")
    displayMessage("Exploring Golang!")
}

// Function to print a custom message
func displayMessage(msg string) {
    fmt.Println("Message received:", msg)
}

Comments

// This is a single-line comment

/* This is a multi-line comment 
   that spans across multiple lines */

If statement

if condition := true; condition {
    fmt.Println("Condition is true!")
}

Go Basic types

Strings

greeting := "Go" + "Lang"

message := `This is a "raw" string
that can span multiple lines.`

// Outputs: 6
fmt.Println(len(greeting))

// Outputs: Go
fmt.Println(string(greeting[0:2]))

Numbers

intValue := 3         // int
floatValue := 3.0     // float64
complexValue := 3 + 4i // complex128
byteValue := byte('b') // byte (alias: uint8)

var unsignedNum uint = 7        // uint (unsigned)
var floatNum float32 = 22.7     // 32-bit float

// Operators
counter := 5
counter++
fmt.Println("counter + 4 =", counter + 4)
fmt.Println("counter * 4 =", counter * 4)

Booleans

isActive   := true
isInactive := false

// Boolean Operators
fmt.Println(isActive && isActive)   // true 
fmt.Println(isActive && isInactive) // false
fmt.Println(isActive || isActive)   // true
fmt.Println(isActive || isInactive) // true
fmt.Println(!isActive)              // false

Arrays

// Array of prime numbers
primeNumbers := [...]int{2, 3, 5, 7, 11, 13}
fmt.Println(len(primeNumbers)) // => 6

// Outputs: [2 3 5 7 11 13]
fmt.Println(primeNumbers)

// Slicing example, Outputs: [2 3 5]
fmt.Println(primeNumbers[0:3])

// String array example
var greetings [2]string
greetings[0] = "Hello"
greetings[1] = "World"

fmt.Println(greetings[0], greetings[1]) // => Hello World
fmt.Println(greetings)   // => [Hello World]

// 2D Array Example
var grid [2][3]int
for i := 0; i < 2; i++ {
    for j := 0; j < 3; j++ {
        grid[i][j] = i + j
    }
}
// => 2D Array:  [[0 1 2] [1 2 3]]
fmt.Println("2D Array: ", grid)

Pointers

package main

import "fmt"

// Main function to demonstrate pointer usage
func main() {
    value := *getPointer()
    fmt.Println("Dereferenced value:", value)
}

// Function that returns a pointer to an integer
func getPointer() (ptr *int) {
    num := 234
    return &num
}

// Alternative pointer creation using `new`
pointer := new(int)
*pointer = 234
fmt.Println("Value through new:", *pointer)

See: See: Pointers

Slices

// Creating a slice with 3 elements
strSlice := make([]string, 3)
strSlice[0] = "a"
strSlice[1] = "b"

// Appending elements to the slice
strSlice = append(strSlice, "d")
strSlice = append(strSlice, "e", "f")

// Output the slice and various properties
fmt.Println(strSlice)       // Output the entire slice
fmt.Println(strSlice[1])    // Output second element
fmt.Println(len(strSlice))  // Output the length of the slice
fmt.Println(strSlice[1:3])  // Slice from index 1 to 3

// Another example of a slice
numSlice := []int{2, 3, 4}

See: See also: Slices example

Constants

// Defining constants
const constantStr string = "constant"
const goldenRatio = 1.618
const largeNumber = 500000000
const result = 3e20 / largeNumber

fmt.Println(result)  // Output the result of the constant calculation

Type conversions

// Type conversions
intValue := 90
floatValue := float64(intValue)  // Convert int to float64
uintValue := uint(intValue)      // Convert int to uint

// Convert int to string, will be equal to character 'Z'
charValue := string(intValue) 

// Converting an int to a string using strconv
import "strconv"

strValue := strconv.Itoa(intValue)
fmt.Println(strValue)  // Outputs: "90"

Go Strings

Strings function

package main

import (
	"fmt"
	str "strings"  // Importing strings package with an alias
)

func main() {
    // Using the strings package with alias 'str'
	fmt.Println(str.Contains("example", "e"))

    // Built-in functions
    fmt.Println(len("world"))  // Outputs: 5
    // Outputs the ASCII value of the character at index 1
	fmt.Println("world"[1])
    // Outputs: 'o'
	fmt.Println(string("world"[1]))
}

fmt.Printf

package main

import (
	"fmt"
	"os"
)

// Defining a struct to represent a point
type coordinate struct {
	x, y int
}

func main() {
	// Creating an instance of the coordinate struct
	point := coordinate{1, 2}
	fmt.Printf("%vn", point)                        // => {1 2}
	fmt.Printf("%+vn", point)                       // => {x:1 y:2}
	fmt.Printf("%#vn", point)                       // => main.coordinate{x:1, y:2}
	fmt.Printf("%Tn", point)                        // => main.coordinate
	fmt.Printf("%tn", true)                         // => true
	fmt.Printf("%dn", 123)                          // => 123
	fmt.Printf("%bn", 14)                           // => 1110
	fmt.Printf("%cn", 33)                           // => !
	fmt.Printf("%xn", 456)                          // => 1c8
	fmt.Printf("%fn", 78.9)                         // => 78.9
	fmt.Printf("%en", 123400000.0)                  // => 1.23e+08
	fmt.Printf("%En", 123400000.0)                  // => 1.23E+08
	fmt.Printf("%sn", ""hello"")                  // => "hello"
	fmt.Printf("%qn", ""hello"")                  // => ""hello""
	fmt.Printf("%xn", "encode this")                // => 656e636f64652074686973
	fmt.Printf("%pn", &point)                       // => 0xc00002c040
	fmt.Printf("|%6d|%6d|n", 12, 345)               // => |    12|   345|
	fmt.Printf("|%6.2f|%6.2f|n", 1.2, 3.45)         // => |  1.20|  3.45|
	fmt.Printf("|%-6.2f|%-6.2f|n", 1.2, 3.45)       // => |1.20  |3.45  |
	fmt.Printf("|%6s|%6s|n", "bar", "x")            // => |   bar|     x|
	fmt.Printf("|%-6s|%-6s|n", "bar", "x")          // => |bar   |x     |

	// Using Sprintf to format a string and assign it to a variable
	result := fmt.Sprintf("a %s", "word")
	fmt.Println(result)

	// Using Fprintf to print an error message to stderr
	fmt.Fprintf(os.Stderr, "an %sn", "issue")
}

See: See also: fmt

Go Flow control

Conditional

value := 10

if value > 20 {
    fmt.Println("Greater than 20")
} else if value < 20 {
    fmt.Println("Less than 20")
} else {
    fmt.Println("Equal to 20")
}

Statements in if

message := "welcome to Go!"

// Using a short declaration inside an if statement
if length := len(message); length > 0 {
    fmt.Println("String is not empty")
}

// Example with function call and error handling
if _, err := performAction(); err != nil {
    fmt.Println("Something went wrong")
}

Switch

value := 42.0

switch value {
case 0:
    // Do nothing for 0
case 1, 2:
    fmt.Println("Matched 1 or 2")
case 42:   // No fall-through behavior here
    fmt.Println("Found the value 42")
case 43:
    fmt.Println("This case won't be reached")
default:
    fmt.Println("This is the default case")
}

See: See: Switch

For loop

for index := 0; index <= 10; index++ {
    fmt.Println("Current index:", index)
}

For-Range loop

numbers := []int{2, 3, 4}
total := 0
for _, value := range numbers {
    total += value
}
fmt.Println("Total:", total)

While loop

counter := 1
for counter <= 3 {
    fmt.Println(counter)
    counter++
}

Continue keyword

for number := 0; number <= 5; number++ {
    if number % 2 == 0 {
        continue  // Skip even numbers
    }
    fmt.Println(number)
}

Break keyword

for {
    fmt.Println("Executing loop")
    break  // Exiting the loop after one iteration
}

Go Structs & Maps

Defining

package main

import (
	"fmt"
)

// Defining a struct to represent a point in 2D space
type Point struct {
	X int
	Y int
}

func main() {
	// Creating an instance of the Point struct
	p := Point{1, 2}
	p.X = 4  // Modifying the X value

	// Printing the updated values of X and Y
	fmt.Println(p.X, p.Y) // => 4 2
}

See: See: Structs

Literals

// Using named fields for initialization
point1 := Point{X: 1, Y: 2}

// Field names can be omitted if the order is known
point2 := Point{1, 2}

// Only the X field is initialized, Y is set to the default zero value (0)
point3 := Point{X: 1}

Pointers to structs

point := &Point{1, 2}  // Create a pointer to a Point struct
point.X = 2             // Modifying the X value

// Accessing through pointer is the same as dereferencing
// This is equivalent to: (*point).X = 2
fmt.Println(point.X)    // => 2

Maps

// Creating a new map with string keys and int values
myMap := make(map[string]int)
myMap["key1"] = 7
myMap["key2"] = 13
fmt.Println(myMap) // => map[key1:7 key2:13]

// Retrieving a value from the map
value1 := myMap["key1"]
fmt.Println(value1)   // => 7
fmt.Println(len(myMap)) // => 2

// Deleting an entry from the map
delete(myMap, "key2")
fmt.Println(myMap) // => map[key1:7]

// Checking if a key exists in the map
_, exists := myMap["key2"]
fmt.Println(exists) // => false

// Initializing a map with values
newMap := map[string]int{"foo": 1, "bar": 2}
fmt.Println(newMap) // => map[bar:2 foo:1]

Go Functions

Multiple arguments

// Function to add two integers
func addTwoNumbers(x int, y int) int {
    return x + y
}

// Function to add three integers
func addThreeNumbers(x, y, z int) int {
    return x + y + z
}

fmt.Println(addTwoNumbers(1, 2))    // Output: 3
fmt.Println(addThreeNumbers(1, 2, 3)) // Output: 6

Multiple return

// Function returning two integer values
func getValues() (int, int) {
    return 3, 7
}

// Assigning the returned values to variables
x, y := getValues()
fmt.Println(x)  // Output: 3
fmt.Println(y)  // Output: 7

Function literals

// Anonymous function that returns two strings
result1, result2 := func() (string, string) {
    words := []string{"hello", "quickref.me"}
    return words[0], words[1]
}()

// Output the results
fmt.Println(result1, result2) // Output: hello quickref.me

Naked returns

// Function to split a sum into two parts
func splitAmount(total int) (part1, part2 int) {
    part1 = total * 4 / 9
    part2 = total - part1
    return part1, part2
}

// Using the split function
amount1, amount2 := splitAmount(17)
fmt.Println(amount1)  // Output: 7
fmt.Println(amount2)  // Output: 10

Variadic functions

// Function to sum any number of integers
func calculateSum(values ...int) {
    fmt.Print(values, " ")  // Print the slice of values
    total := 0
    for _, value := range values {
        total += value
    }
    fmt.Println(total)  // Print the total sum
}

// Calling the function with different sets of numbers
calculateSum(1, 2)        // Output: [1 2] 3
calculateSum(1, 2, 3)     // Output: [1 2 3] 6

// Passing a slice to the function
numbers := []int{1, 2, 3, 4}
calculateSum(numbers...)  // Output: [1 2 3 4] 10

init function

import "fmt"

// Global variable
var number = initializeNumber()

// Function to initialize the number
func initializeNumber() int {
    return 42
}

// init function to modify the global variable
func init() {
    number = 0
}

func main() {
    fmt.Println(number) // Output: 0
}

Functions as values

import "fmt"

func main() {
    // Assign an anonymous function to the variable 'add'
    sum := func(a, b int) int {
        return a + b
    }

    // Call the function using the variable 'sum'
    fmt.Println(sum(3, 4)) // Output: 7
}

Closures 1

import "fmt"

// Function that returns a closure
func createClosure() func() int {
    outerValue := 2
    closure := func() int {
        return outerValue
    }
    return closure
}

func main() {
    // Calling the returned closure function
    fmt.Println(createClosure()()) // Output: 2
}

Closures 2

import "fmt"

// Function that returns a closure and a value
func outer() (func() int, int) {
    outerValue := 2
    // Define the closure that modifies the outer variable
    inner := func() int {
        outerValue += 99
        return outerValue
    }
    inner()  // Call the closure once to modify the outer variable
    return inner, outerValue  // Return the closure and the modified value
}

func main() {
    // Call the outer function to get the closure and the value
    innerFunc, value := outer()

    // Output the results
    fmt.Println(innerFunc()) // Output: 200
    fmt.Println(value)       // Output: 101
}

Go Packages

Importing

import "fmt"
import "math/rand"

import (
    "fmt"        // fmt package provides formatted I/O functions like fmt.Println
    "math/rand"  // rand package provides functions for generating random numbers like rand.Intn
)

See: See: Importing

Aliases

import (
    "fmt"
    r "math/rand" // Alias 'r' for 'math/rand' package
)

func main() {
    // Using the alias 'r' to call Intn function from math/rand
    fmt.Println(r.Intn(100)) // Generates a random number between 0 and 99
}

Packages

package main

// Internal packages can only be imported by other packages within the same module
// or the module that is within the tree rooted at the parent of the 'internal' directory.
import (
    "fmt"
    "yourmodule/internal" // Importing the internal package from your module
)

func main() {
    fmt.Println("Internal package example")
    // You can now use functions or types from the 'internal' package within your module.
}

See: See: Internal packages

Exporting names

// Begin with a capital letter to make the function accessible outside the package
func Hello() {
    // Function body
    fmt.Println("Hello, World!")
}

See: See: Exported names

Go Concurrency

Goroutines

package main

import (
	"fmt"
	"time"
)

// Function f prints a message along with a counter
func f(from string) {
	for i := 0; i < 3; i++ {
		fmt.Println(from, ":", i)
	}
}

func main() {
	// Calling f directly in the main goroutine
	f("direct")

	// Calling f in a new goroutine
	go f("goroutine")

	// Calling an anonymous function in a new goroutine
	go func(msg string) {
		fmt.Println(msg)
	}("going")

	// Sleep to allow goroutines to finish execution before the main goroutine ends
	time.Sleep(time.Second)

	// Main program is done
	fmt.Println("done")
}

See: See: Goroutines

WaitGroup

package main

import (
	"fmt"
	"sync"
	"time"
)

// Function w performs some work (simulated with sleep) and then notifies the WaitGroup.
func w(id int, wg *sync.WaitGroup) {
	defer wg.Done() // Decrement the counter when the goroutine completes.
	fmt.Printf("%d startingn", id)

	// Simulate work with sleep
	time.Sleep(time.Second)
	
	fmt.Printf("%d donen", id)
}

func main() {
	var wg sync.WaitGroup // WaitGroup to synchronize goroutines.
	
	// Loop to create 5 goroutines
	for i := 1; i <= 5; i++ {
		wg.Add(1) // Increment the counter for each goroutine.
		go w(i, &wg) // Start a new goroutine.
	}

	// Wait until all goroutines are done.
	wg.Wait()
}

See: See: WaitGroup

Closing channels

ch <- 1  // Send value '1' to the channel 'ch'
ch <- 2  // Send value '2' to the channel 'ch'
ch <- 3  // Send value '3' to the channel 'ch'
close(ch) // Closes the channel 'ch', no more values can be sent

// Iterate over the channel until it's closed
for i := range ch {
    // `i` will receive values from the channel one by one.
    // This loop will stop when the channel is closed and all values are read.
    fmt.Println(i)
}

// Receiving from a closed channel and checking if it's closed
v, ok := <- ch
// `v` will hold the value received from the channel, and `ok` will be false if the channel is closed.
fmt.Println(v, ok) // If channel is closed, `ok` will be false, and `v` will be the zero value for the type.

See: See: Range and close

Buffered channels

ch <- 1
ch <- 2
ch <- 3
close(ch) // Closes a channel

// Iterate the channel until closed
for i := range ch {
  fmt.Println(i)
}

// Closed if `ok == false`
v, ok := <- ch
fmt.Println(v, ok)

See: See: Buffered channels

Go Error control

Deferring functions

package main

import "fmt"

func main() {
  // Defer the execution of the anonymous function
  defer func() {
    fmt.Println("Finished")
  }()
  
  fmt.Println("In Progress...")
}

Lambda defer

func main() {
  var d = int64(0)
  defer func(d *int64) {
    fmt.Printf("& %v Unix Secn", *d)
  }(&d)
  fmt.Print("Done ")
  d = time.Now().Unix()
}

Defer

func main() {
  defer fmt.Println("Completed")
  fmt.Println("In Progress...")
}

See: See: Defer, panic and recover

Go Methods

Receivers

type Point struct {
  X, Y float64
}

func (p Point) Distance() float64 {
  return math.Sqrt(p.X * p.X + p.Y * p.Y)
}

p := Point{1, 2}
p.Distance()

See: See: Methods

Mutation

func (p *Point) Stretch(factor float64) {
  p.X = p.X * factor
  p.Y = p.Y * factor
}

p := Point{6, 12}
p.Stretch(0.5)
// `p` is updated

See: See: Pointer receivers

Go Interfaces

A basic interface

type Figure interface {
  CalculateArea() float64
  CalculatePerimeter() float64
}

Struct

type Rectangle struct {
  Length, Width float64
}

func (r Rectangle) CalculateArea() float64 {
  return r.Length * r.Width
}

func (r Rectangle) CalculatePerimeter() float64 {
  return 2 * (r.Length + r.Width)
}
// Rectangle implicitly implements the Figure interface by providing methods CalculateArea and CalculatePerimeter

Methods

func (r Rectangle) CalculateArea() float64 {
  return r.Length * r.Width
}

func (r Rectangle) CalculatePerimeter() float64 {
  return 2 * (r.Length + r.Width)
}
// The methods CalculateArea and CalculatePerimeter in Rectangle satisfy the GeometricFigure interface

Interface example

func main() {
  var r Shape = Rectangle{Length: 3, Width: 4}
  fmt.Printf("Type of r: %T, Area: %.2f, Perimeter: %.2f.", r, r.CalculateArea(), r.CalculatePerimeter())
}

Miscellaneous

Keywords

breakdefaultfunc
interfaceselectcase
defergomap
structchanelse
gotopackageswitch
constfallthroughif
rangetypecontinue
forimportreturn
var

Operators and punctuation

+&+=&=&&==!=
()-|-=|=||
<<=[]*^*=
^=<->>={}/
<</=<<=++=:=,
;%>>%=>>=--!
....:&^&^=