string & “strings” package#

  • A string in Go is an immutable sequence of bytes.
  • Strings usually contain UTF-8 encoded text.
  • Because strings are immutable, any modification creates a new string instead of changing the original one.
s := "Hello"
s[0] = "h"  // invalid
  • String Declaration
var name string = "John" // Using explicit type
name := "John" // Using type inference
  • String Concatenation - using the + operator
firstName := "John"  
lastName := "Doe"  
  
fullName := firstName + " " + lastName
  • Escape Characters - Special characters can be used inside strings.
    • \n → New line
    • \t → Tab
    • \" → Double quote
    • \\ → Backslash
text := "Hello\nWorld"
  • Raw Strings - use backticks (`) and preserve formatting. No escaping is required.
text := `Hello  
World`
  • String Length - Use the built-in len() function. len() returns the number of bytes, NOT necessarily the number of characters.
s := "hello"  
length := len(s)
  • strings Package - The strings package provides many utility functions for string manipulation.
import "strings"
  • Commonly used functions.
FunctionDescriptionExampleResult
strings.ToLower()Converts all characters to lowercasestrings.ToLower(“HELLO”)“hello”
strings.ToUpper()Converts all characters to uppercasestrings.ToUpper(“hello”)“HELLO”
strings.Compare()Lexicographically compares two stringsstrings.Compare(“abc”,“abc”)0
strings.Contains()Checks if substring existsstrings.Contains(“hello world”,“world”)true
strings.ContainsAny()Checks if any character from set existsstrings.ContainsAny(“team”,“ae”)true
strings.ContainsRune()Checks if rune existsstrings.ContainsRune(“hello”,’e')true
strings.ContainsFunc()Checks if any rune satisfies a conditionstrings.ContainsFunc(“Hello”, unicode.IsUpper)true
strings.Count()Counts occurrences of substringstrings.Count(“banana”,“a”)3
strings.HasPrefix()Checks if string starts with prefixstrings.HasPrefix(“golang”,“go”)true
strings.HasSuffix()Checks if string ends with suffixstrings.HasSuffix(“file.txt”,".txt")true
strings.Index()Returns first occurrence indexstrings.Index(“hello”,“l”)2
strings.LastIndex()Returns last occurrence indexstrings.LastIndex(“hello”,“l”)3
strings.Join()Joins slice elements into a stringstrings.Join([]string{“go”,“is”,“fun”}," “)“go is fun”
strings.Split()Splits string into slicestrings.Split(“a,b,c”,”,")[“a”,“b”,“c”]
strings.Replace()Replaces substring occurrences (limited count)strings.Replace(“foo bar foo”,“foo”,“baz”,1)“baz bar foo”
strings.ReplaceAll()Replaces all occurrencesstrings.ReplaceAll(“foo bar foo”,“foo”,“baz”)“baz bar baz”
strings.Trim()Removes specified characters from both endsstrings.Trim("!!hello!!","!")“hello”
strings.TrimSpace()Removes leading and trailing spacesstrings.TrimSpace(" hello “)“hello”
strings.Lines()Returns iterator over linesstrings.Lines(“a\nb\nc”)line iterator
  • String Builder
var builder strings.Builder
builder.WriteString("Hello")
builder.WriteString(", ")
builder.WriteString("world!")
fmt.Println(builder.String()) // Output: Hello, world!

rune#

  • A rune represents a Unicode code point. rune is an alias for int32.
  • It is commonly used to represent individual Unicode characters.
  • Strings in Go are byte sequences (UTF-8). Some characters require multiple bytes, so indexing a string gives bytes, not characters. rune helps correctly work with Unicode characters.
s := "Go"  
  
b := s[0] // byte  
r := rune(s[0]) // rune

// rune literal
r := 'A'  
r := '你'  
r := '🙂'  
  • Byte vs Rune
TypeSizeUsage
byte8-bitraw data / ASCII
rune32-bitUnicode character
  • Iterating Over Runes in a String - Using range automatically decodes UTF-8 into runes.
s := "Hello" 
for i, r := range s {  
	fmt.Println(i, r)  
}

//Converting string to rune
s := "hello"
r := []rune(s)  // This allows **safe character indexing**.  
r[0]  

// Rune to string
r := 'A'
s := string(r)  

// Check if its a unicode char
unicode.IsLetter(r)

// Length
s := "你好"  
len(s) // Length in bytes
length := len([]rune(s)) // Actual character length i.e converts the string into **Unicode code points** then count.

import "unicode/utf8"
length := utf8.RuneCountInString(s) // actual length

Operators#

  • Arithmetic
  • Assignment
  • Comparison
  • Logical
  • Increment / Decrement
  • Bitwise

Arrays & Slices#

  • Arrays
    • Arrays are fixed-size collections of elements of the same type.
    • Arrays have fixed size.
    • Size is part of the array type.
    • Arrays are value types (copied when passed to functions).
    • Array type includes both size and element type: [5]int and [10]int are different types
var arr [5]int // Decleration  
arr := [5]int{1, 2, 3, 4, 5}  // Initialization
arr := [...]int{1, 2, 3, 4}  // Size Inference

arr[0], arr[1] // Accessing Elements
arr[2] = 10  // Updating Elements
len(arr) // Length of the array

var a = [4]int{0: 10, 3: 2} // Specific elements are initialized rest all, default value
  • Slices
    • Slices are dynamic, flexible views over arrays.
    • They are used more frequently than arrays in Go.
    • Syntax
      • slice[start:end]
      • Rules
        • start → inclusive
        • end → exclusive
        • default start → 0
        • default end → len(slice)
    • len(s), cap(s)
      • len → number of elements
      • cap → underlying array capacity
    • append function returns a new Slice
    • Slices internally reference an underlying array.
    • No direct delete functionality exists. To delete the elements use the append & slicing functionality to achieve the same.
var s []int  // Decleration
s := []int{1, 2, 3, 4} // Initialization

arr := [5]int{1,2,3,4,5}  
s := arr[1:4]   // Creating slices from array

s := []int{0,1,2,3,4,5}  
s[1:4]  // slice starting from index 1 to 3
s[:3]  // slice starting from start to index 2
s[2:]  // slice starting from index 2 to end
s[:] // slice starting from start to end

s := []int{1,2,3}  
s = append(s, 4)  // Add single element
s = append(s, 5, 6, 7)  // Add multiple element
b := []int{3,4}
a = append(a, b...) // Add another slice

s := make([]int, 5)  // creating with preferred len & capacity
s := make([]int, 5, 10)  
FeatureArraysSlices
SizeFixedDynamic
Declaration[5]int[]int
UsageRareVery common
Passed to functionsCopiedReference-like
MemoryEntire arrayReference to array
  • Copy function
copy(destination, source) // works on slices

var s = []int{12, 23, 34}
var sn = make([]int, len(s)) var n = copy(sn, s) // var n is the number of copied elements

Struct#

  • A struct is a user-defined type that groups related fields (variables) together.
  • It is similar to a class in other languages, but without inheritance.
// Defining
type Person struct { // struct type
	name string // Fields
	age  int
}

// Creating instance
p := Person{
        name: "John",
        age:  25,
        }
p2 := Person{"John", 25}
p3 := new(Person)

// Accessing fields & modifying
p.name
p.age
p.name = "New Name"
  • Exported vs Unexported Fields, Field visibility depends on capitalization.
Field NameVisibility
nameprivate (same package only)
Nameexported (accessible outside package)
  • Struct with Constructor Pattern, Go does not have constructors, but factory functions are commonly used.
func NewPerson(name string, age int) Person {
	return Person{
		name: name,
		age:  age,
	}
}

p := NewPerson("John", 25)
  • Struct Comparison - structs can be compared if all fields are comparable.
p1 := Person{"John", 25}
p2 := Person{"John", 25}

p1 == p2 // true
  • Anonymous Struct - Structs can be created without defining a type.
p := struct {
		name string
		age  int
	}{
		name: "John",
		age:  25,
	}

Looping#

  • Basic used when the number of iterations is known.
/*for init; condition; post {  
    loop body  
} */

for i := 0; i < 5; i++ {  
	fmt.Println(i)  
}  
  • while style loop
i := 0  
  
for i < 5 {  
	fmt.Println(i)  
	i++  
}  
  • Infinite Loop - Runs indefinitely until stopped with break or return.
for {  
	fmt.Println("Running forever")  
}
  • for-range Loop - Used to iterate over arrays, slices, maps, strings, and channels.
items := []string{"a", "b", "c"}  
  
for index, value := range items {  
	fmt.Println(index, value)  
}  
  • Ignoring Values in range - Use _ to ignore index or value.
// Ignoring Index
for _, value := range items {  
fmt.Println(value)  
}  
  
// Ignore value
for index, _ := range items {  
fmt.Println(index)  
}  
  • break Statement - Used to exit a loop immediately.
for i := 0; i < 10; i++ {  
	if i == 5 {  
		break  
	}  
	fmt.Println(i)  
}  
  • continue Statement - Skips the current iteration and moves to the next one.
for i := 0; i < 5; i++ {  
	if i == 2 {  
		continue  
	}  
	fmt.Println(i)  
}  

“time” package#

  • The time package provides functionality for working with time, dates, durations, and formatting. Documentation - https://pkg.go.dev/time
import "time" 
  • Current Time - Get the current local time.
now := time.Now() // Returns time.Time  
  • Creating Specific Time
t := time.Date(  
	2024,  // year
	time.January, // month 
	10,  // day
	15,  // hour
	30,  // minutes
	0,  // seconds
	0,  // nanoseconds
	time.UTC,  // location
)  
  • Time Parsing (String → time) - Convert a string into time.Time using Parse.
    • Go uses a reference time layout => Mon Jan 2 15:04:05 MST 2006
date := "Tue, 09/22/1995, 13:00"  
layout := "Mon, 01/02/2006, 15:04"  
  
t, err := time.Parse(layout, date)  
  • Time Formatting (time → String) - Convert time.Time to a string.
t := time.Now()  
  
formatted := t.Format("2006-01-02 15:04:05")  
  • Comparing Times
t1.After(t2)  // true if `t1` is after `t2`
t1.Before(t2)  // true if `t1` is before `t2`
t1.Equal(t2) // Checks if both times are equal
  • Time Duration - Duration represents the elapsed time between two instants.
duration := time.Hour  
duration := 30 * time.Minute  

Common durations

ConstantMeaning
time.Nanosecond1 nanosecond
time.Microsecond1 microsecond
time.Millisecond1 millisecond
time.Second1 second
time.Minute1 minute
time.Hour1 hour
  • Measuring Execution Time
start := time.Now()  
  
// code execution  
  
elapsed := time.Since(start)   // Performance measurement
  • Adding or Subtracting Time
t := time.Now()  
future := t.Add(2 * time.Hour)  

diff := t1.Sub(t2) // Returns time.Duration
  • Unix Time - Unix timestamp represents seconds since Jan 1, 1970 (UTC).
t := time.Now()  
ts := t.Unix() // Get Unix time

t := time.Unix(1700000000, 0) // Create time from unix