Golang Cheatsheet

Table of contents

Setup on new machine

Check go.dev for the latest version of golang.

$ cd Downloads
$ wget https://go.dev/dl/go1.19.2.linux-amd64.tar.gz
$ sudo rm -rf /usr/local/go 
$ sudo tar -C /usr/local/ -xzf go1.19.2.linux-amd64.tar.gz

I like my go libraries to be stored in a .go folder in $HOME

$ cd ~
$ mkdir .go
$ cd .go
$ mkdir bin pkg src

Add these to your .bashrc|.zshrc|.bash_profile:

$ vim ~/.zshrc

# Just Go Things
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/.go
export PATH=$PATH:$GOPATH/bin

Should be good after That!


Initialize project

# Create new directory
$ mkdir test-project

# Change into directory and initialize
$ cd test-project
$ go mod init test-project

# Create main go file
$ touch main.go

If you have dependencies you need to download, put the import into the main go file then run:

$ go mod tidy

Troubleshooting

cannot slice str (variable of type *[]string)

DOESN’T WORK:

package main

import "fmt"

func changeSlice(str *[]string) {
  str = str[:len(str)-1]
}

func main() {
  str := []string{"hello", "there", "world"}

  fmt.Println(str)
  changeSlice(&str)
  fmt.Println(str)
}

WILL WORK:

package main

import "fmt"

// You have to dereference just the str
func changeSlice(str *[]string) {
  *str = (*str)[:len((*str))-1]
}

func main() {
  str := []string{"hello", "there", "world"}

  fmt.Println(str)
  changeSlice(&str)
  fmt.Println(str)
}

Useful Snippets

Project Header

//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//  
// Tyler(UnclassedPenguin) PROJECT TITLE 2022
//  
// Author: Tyler(UnclassedPenguin)
//    URL: https://unclassed.ca
// GitHub: https://github.com/UnclassedPenguin
//
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------

Check if item is in slice

func contains(str string, s []string) bool {
  for _, v := range s {
    if v == str {
      return true
    }
  }
  return false
}

Usage:

list := []string{"thing1", "thing2", "thing3"}

if contains("thing1", list) // returns true
if contains("thing8", list) // returns false

Get index of element in slice

func indexOf(str string, s []string) (int) {
  for i, v := range s {
    if v == str {
      return i
    }
  }
  return -1    //not found.
}

Usage:

list := []string{"thing1", "thing2", "thing3"}

indexOfThing1 := indexOf("thing1", list) // 0
indexOfThing2 := indexOf("thing2", list) // 1
indexOfThing3 := indexOf("thing3", list) // 2
indexOfThing8 := indexOf("thing8", list) // -1

A function to print a string of text to the terminal character by character. Sort of emulates someone typing it out, or loading it in from a slow internet connection.

// Requires "fmt", "time", "strings"

func printSlow(str string) {
  stringSplit := strings.Split(str, "")
  for _, l := range stringSplit {
    if l != " " {
      fmt.Print(l)
      time.Sleep(50 * time.Millisecond)
    } else {
      fmt.Print(l)
      time.Sleep(100 * time.Millisecond)
    }
  }
  fmt.Print("\n")
}

Example:

package main

import (
  "fmt"
  "time"
  "strings"
  "flag"
)

func printSlow(str string) {
  if slowMode {
    stringSplit := strings.Split(str, "")
    for _, l := range stringSplit {
      if l != " " {
        fmt.Print(l)
        time.Sleep(50 * time.Millisecond)
      } else {
        fmt.Print(l)
        time.Sleep(100 * time.Millisecond)
      }
    }
    fmt.Print("\n")
  } else {
    fmt.Println(str)
  }
}

var slowMode bool

func main() {

  flag.BoolVar(&slowMode, "s", false, "Print in slow mode")
  flag.Parse()

  if slowMode {
    printSlow("SlowMode: true")
  } else {
    printSlow("SlowMode: false")
  }

  str := "This is a string to print slow."
  printSlow(str)
  str2 := "This is also a string to print slow."
  printSlow(str2)
}

Reverse order of slice

package main

import (
  "fmt"
)

// Reverses the order of a slice
func reverse(slice []int) {
  for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
    slice[i], slice[j] = slice[j], slice[i]
  }
}

func main() {
  slice := []int{0,1,2,3,4,5,6,7,8,9}
  reverse(slice)
  fmt.Println(slice)
}

Output:

[9,8,7,6,5,4,3,2,1,0]

Shuffle a slice

package main

import (
  "fmt"
  "math/rand"
  "time"
)

// Shuffles a slice into a random order
func shuffle(slice []int) {
  rand.Seed(time.Now().UnixNano())
  rand.Shuffle(len(slice), func(i, j int){
    slice[i], slice[j] = slice[j], slice[i]
  })
}

func main() {
  slice := []int{0,1,2,3,4,5,6,7,8,9}
  shuffle(slice)
  fmt.Println(slice)
}

Output:

[8 1 7 9 4 2 0 5 3 6]

Of course, that output is just an example. Since it is random, it will be always be different.