Fundamental Go Programming Constructs and Syntax

Variable Declaration and Type Inference

Go supports short variable declaration using the := operaotr, which automatically infers the data type based on the assigned value.

package main

import "fmt"

func main() {
    username := "Alice"
    fmt.Println(username)
}

Output:

Alice

Formatted Output with Printf

The fmt.Printf function allows for formatted printing. Common verbs include %T for type, %d for integers, and %p for memory addresses.

package main

import "fmt"

func main() {
    user := "Bob"
    age := 30
    fmt.Println(user, age)
    // Print types
    fmt.Printf("%T,%T\n", user, age)
}

Output:

Bob 30
string,int

Memory addresses remain consistent even when the variable value changes.

package main

import "fmt"

func main() {
    score := 100
    fmt.Printf("Value: %d, Address: %p\n", score, &score)
    
    score = 200
    fmt.Printf("Value: %d, Address: %p\n", score, &score)
}

Swapping Values

Go allows simultaneous assignment, making variable swapping concise without a temporary variable.

package main

import "fmt"

func main() {
    x, y := 5, 10
    fmt.Println(x, y)
    x, y = y, x
    fmt.Println(x, y)
}

Output:

5 10
10 5

Anonymous Variables

When a function returns multiple values but only some are needed, the underscore _ acts as an anonymous variable to discard unwanted results.

package main

import "fmt"

func getStatus() (int, string) {
    return 200, "OK"
}

func main() {
    // Only capture the status code
    code, _ := getStatus()
    fmt.Println(code)
}

Variable Scope

Global variables must be declared using var. Local variables can shadow global variables within their scope.

package main

import "fmt"

var message = "Global Scope"

func show() {
    fmt.Println(message)
}

func main() {
    show()
    // Local shadowing
    message := "Local Scope"
    fmt.Println(message)
}

Output:

Global Scope
Local Scope

Constants and Iota

Constants are defined using const. The iota keyword acts as an auto-incrementing counter within a constant block, resetting at each new const declaration.

package main

import "fmt"

func main() {
    const (
        a = iota // 0
        b        // 1
        c = "text"
        d        // "text"
        e = 10
        f        // 10
        g = iota // 7 (index in block)
    )
    fmt.Println(a, b, c, d, e, f, g)
}

Basic Data Types

Boolean types default to false. Numeric types default to 0.

package main

import "fmt"

func main() {
    var isActive bool
    var count int = 50
    var price float64 = 19.99
    
    fmt.Printf("Type: %T, Value: %t\n", isActive, isActive)
    fmt.Printf("Type: %T, Value: %d\n", count, count)
    fmt.Printf("Type: %T, Value: %.1f\n", price, price)
}

Characters and Runes

Single quotes denote a rune (int32), while double quotes denote a string.

package main

import "fmt"

func main() {
    var char rune = 'A'
    var text string = "A"
    
    fmt.Printf("Rune Value: %d\n", char)
    fmt.Printf("String Value: %s\n", text)
}

Type Conversion

Go requires explicit type conversion; implicit casting is not supported.

package main

import "fmt"

func main() {
    whole := 10
    decimal := 10.5
    
    // Explicit conversion
    f := float64(whole)
    i := int(decimal)
    
    fmt.Printf("%T\n", f)
    fmt.Printf("%T\n", i)
}

Operators and Input

Increment operators like ++ are statements, not expressions, so they cannot be used inside fmt.Println.

package main

import "fmt"

func main() {
    val := 10
    val++ 
    fmt.Println(val) // Valid
    // fmt.Println(val++) // Invalid
}

Reading user input can be done using fmt.Scanln.

package main

import "fmt"

func main() {
    var input int
    fmt.Println("Enter a number:")
    fmt.Scanln(&input)
    fmt.Println("Received:", input)
}

Switch Statements

Switch cases can include multiple conditions. The fallthrough keyword allows execution to continue into the next case.

package main

import "fmt"

func main() {
    grade := 85
    switch {
    case grade >= 90:
        fmt.Println("A")
    case grade >= 80:
        fmt.Println("B")
        fallthrough
    case grade >= 70:
        fmt.Println("C")
    default:
        fmt.Println("F")
    }
}

String Handling

The len function returns the byte length, which may differ from character count for multi-byte Unicode characters. Iterating with range yields runes.

package main

import "fmt"

func main() {
    text := "Hello 世界"
    fmt.Println("Byte Len:", len(text))
    
    for index, char := range text {
        fmt.Printf("Index: %d, Char: %c\n", index, char)
    }
}

Functions and Closures

Functions are first-class types. Closures allow inner functions to capture variables from the outer scope.

package main

import "fmt"

func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    next := counter()
    fmt.Println(next()) // 1
    fmt.Println(next()) // 2
}

Deferred Execution

The defer keyword schedules a function call to run after the surrounding function completes. Deferred calls are executed in LIFO order.

package main

import "fmt"

func main() {
    defer fmt.Println("First")
    defer fmt.Println("Second")
    fmt.Println("Immediate")
}

Output:

Immediate
Second
First

Arrays and Slices

Arrays are value types, while slices are reference types pointing to underlying arrays.

package main

import "fmt"

func modifySlice(s []int) {
    s[0] = 99
}

func main() {
    data := []int{1, 2, 3}
    modifySlice(data)
    fmt.Println(data) // [99 2 3]
}

Slices can be expanded using append. If capacity is exceeded, a new underlying array is allocated.

package main

import "fmt"

func main() {
    s := []int{1, 2}
    s = append(s, 3, 4)
    fmt.Println(s)
}

Error Handling

Go uses explicit error returns. panic stops execution, while recover inside a deferred function can regain control.

package main

import (
    "errors"
    "fmt"
)

func safeDivide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

func main() {
    res, err := safeDivide(10, 0)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println(res)
    }
}

Time Package

The standard library provides robust time handling capabilities.

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Println("Year:", now.Year())
    fmt.Println("Weekday:", now.Weekday())
}

Tags: Golang slices closures error-handling standard-library

Posted on Sun, 07 Jun 2026 16:33:16 +0000 by duckduckgoose