Vee's Golang Notes

Types and Operators

21 Sep 2025

Types and Operators

Types and Variables

  • A type defines the kind of value and how it is stored in memory.
  • A variable is a named chunk of memory that holds a value of a specific type.
  • In Go, every variable has a type, though Go can often infer it for you.
package main
 
import "fmt"
 
func main() {
    var total int // declares a variable of type int
    fmt.Println(total)
}

Fundamental Types

Go provides a set of basic (primitive) types:

CategoryTypes
Booleanbool
Integersint, int8, int16, int32, int64
uint, uint8 (byte), uint16, uint32, uint64, uintptr
Floating Pointfloat32, float64
Complexcomplex64, complex128
Textstring, rune (alias for int32, represents a Unicode code point)

Go integers (int/uint) are machine dependent (32-bit or 64-bit).
rune is used for Unicode characters, while byte is an alias for uint8.


Standard Library Types

The standard library adds many useful types:

  • time.Time – working with dates and times (time package)
  • big.Int, big.Float – arbitrary precision numbers (math/big)
  • slice – dynamic array-like sequences
  • map – key/value store
  • struct – custom aggregate type
  • array – fixed-length sequence
  • channel – communication between goroutines

Strings

Strings are immutable sequences of bytes (UTF-8 encoded).

package main
 
import (
    "fmt"
)
 
func main() {
    var first, second string
    fmt.Print("First name: ")
    fmt.Scan(&first)
    fmt.Print("Second name: ")
    fmt.Scan(&second)
    fmt.Println("Hello", first+" "+second)
}

+ concatenates strings.


Variable Names

Rules:

  • May contain letters, digits, and underscores.
  • Must start with a letter or underscore.
  • Case-sensitive (totalTotal).
  • Cannot be a Go keyword (func, var, etc.).

Conventions:

  • lowerCamelCase for local variables.
  • UpperCamelCase to export names outside a package.

Literal Constants

Literal values are typed:

42          // int
3.14        // float64
'a'         // rune
"hello"     // string
0xff        // hexadecimal
0b1010      // binary (Go 1.13+)

Escape sequences inside strings: \n (newline), \\ (backslash), \t (tab).


Variable Declarations and Initialization

Go offers several ways to declare variables:

var i int = 33     // explicit type and value
var c rune = 'a'   // single quotes for runes
var d = 3.14983    // type inferred (float64)
x := 10            // short declaration with inference

Go automatically zero-initializes variables:

  • Numbers → 0
  • Booleans → false
  • Strings → ""
  • Pointers, slices, maps → nil

Type Inference

The := operator infers the type from the initializer:

i := 3       // int
d := 3.4     // float64
city := "Accra" // string
r := city[0] // byte

Pointers

A pointer holds the address of a value.

package main
import "fmt"
 
func main() {
    x := 42
    p := &x        // pointer to x
    fmt.Println(*p) // dereference
    *p = 100
    fmt.Println(x) // 100
}

Unlike C++, Go has no pointer arithmetic.


References

Go does not have C++-style references.
Function arguments are passed by value, but you can pass a pointer to modify the original:

func increment(n *int) {
    *n++
}

Enumerations

Go uses iota to create enumerated constants:

type Choice int
 
const (
    No Choice = iota
    Yes
)
 
var value Choice = Yes
fmt.Println(value) // 1

iota auto-increments within a const block.


Arrays and Slices

  • Arrays have a fixed length.
  • Slices are dynamically sized and far more common.
var arr [3]int         // array of 3 ints
nums := []int{1, 2, 3} // slice
nums = append(nums, 4) // add element
fmt.Println(nums[0])

Indexing starts at 0.


Strings as Byte Arrays

Strings are read-only byte slices.
To modify, convert to a slice of []rune or []byte:

s := "Go"
b := []byte(s)
b[0] = 'N'
fmt.Println(string(b)) // "No"

Structs

A struct groups related fields:

type Car struct {
    RegNo   string
    Model   string
    Year    int
    Mileage float64
}
 
func main() {
    mine := Car{RegNo: "GX123", Model: "Land Rover", Year: 2013}
    yours := mine
    fmt.Println(yours.Model)
}

Constants and const / constexpr

Go’s const declares compile-time constants:

const Pi = 3.14159
const BufferSize = 1024

No constexpr is needed—const already implies compile-time evaluation.


Operators in Go

Operators are symbols that perform actions on values and variables to produce a result.
Go supports:

  • Arithmetic
  • Relational (Comparison)
  • Logical
  • Bitwise
  • Assignment
  • Unary (single operand)

There is no ternary (?:) operator in Go.


Arithmetic Operators

OperatorMeaningExample
+Addition / unary plusx + y, +x
-Subtraction / unary minusx - y, -x
*Multiplicationx * y
/Divisionx / y
%Modulus (remainder)x % y
  • Integer division truncates toward zero.
  • % is only defined for integers.
a, b := 7, 3
fmt.Println(a/b) // 2  (integer division)
fmt.Println(a%b) // 1

Relational (Comparison) Operators

All comparisons return a bool:

OperatorMeaning
==Equal
!=Not equal
<Less than
<=Less than or equal
>Greater than
>=Greater than or equal
x, y := 10, 20
fmt.Println(x < y)  // true
fmt.Println(x == y) // false

Logical Operators

Operate on boolean values:

OperatorMeaning
!Logical NOT (!expr)
&&Logical AND (a && b)
`

Go uses short-circuit evaluation:

  • a && b: if a is false, b is not evaluated.
  • a || b: if a is true, b is not evaluated.
if found && ptr != nil && *ptr == 'G' {
    fmt.Println("Match!")
}

Assignment Operators

Assign values to variables:

OperatorExampleEquivalent
=x = yassign y to x
+=x += yx = x + y
-=x -= yx = x - y
*=x *= yx = x * y
/=x /= yx = x / y
%=x %= yx = x % y
&=x &= ybitwise AND
`=``x
^=x ^= ybitwise XOR
<<=x <<= yleft shift
>>=x >>= yright shift
total := 10
total += 5 // 15

Increment & Decrement

Go provides ++ and -- as statements only, not expressions.

i := 5
i++ // i = i + 1
i-- // i = i - 1

❗ Unlike C++, ++i and i++ are identical in Go and cannot be used inside expressions:

fmt.Println(i++) // ❌ compile error

Bitwise Operators

Work on integers at the bit level:

OperatorMeaning
&Bitwise AND
``
^Bitwise XOR (toggle bits)
&^Bit clear (AND NOT)
<<Left shift
>>Right shift
a, b := 6, 3
fmt.Println(a & b) // 2  (110 & 011)
fmt.Println(a | b) // 7  (110 | 011)
fmt.Println(a ^ b) // 5  (110 ^ 011)
fmt.Println(a &^ b)// 4  (bit clear)

Operator Precedence & Associativity

Expressions are evaluated based on precedence (order of importance) and associativity (direction of grouping).

Example:

result := 3*4 + 8*6*2
fmt.Println(result) // 108

Order:

  1. * and / before + and -.
  2. Operators of the same precedence associate left to right.
  3. Assignment (=) associates right to left.

Parentheses () override precedence.


Type Conversion

Go does not perform implicit numeric conversions.
You must use explicit conversion to change types.

var i int = 3
var f float64 = float64(i) // explicit
fmt.Println(f)

Mixing types without conversion is a compile-time error.


No Ternary Operator

Go deliberately omits the ?: operator.
Use if instead:

x, y := 10, 20
var max int
if x > y {
    max = x
} else {
    max = y
}