# Odin Quickstart Reference - Quick Reference - Launch Pad

__ _______________________ _________._________________________ \_ _____/ \______ \ / _ \ / _____/ / _____/ | | \_ _____/ | __) | _/ / /_\ \ / \ ___ / \ ___ | | | __)_ | \ | | \ / | \ \ \_\ \ \ \_\ \ | |___ | \ \___ / |____|_ / \____|__ / \______ / \______ / |_______ \ /_______ / \/ \/ \/ \/ \/ \/ \/

# Odin Quickstart Reference

← Back to quick reference

← Home

Quick reference guide for Odin. Essential syntax, types, control flow, and common patterns for the Odin programming language.

## Hello World

    package main

    import "core:fmt"

    main :: proc() {
        fmt.println("Hello, World!")  // Odin keeps it clean and readable.
    }

## Variables

    x: int = 42
    name: string = "Alice"
    flag: bool = true
    pi: f64 = 3.14

    // Type inference with :=
    y := 100              // Compiler infers int
    text := "Hello"       // Compiler infers string

    // Multiple declarations
    a, b, c: int = 1, 2, 3

## Control Flow

### If/Else

    if x > 10 {
        fmt.println("x is big")
    } else {
        fmt.println("x is small")
    }

    if x > 10 {
        fmt.println("big")
    } else if x > 5 {
        fmt.println("medium")
    } else {
        fmt.println("small")
    }

    // If as expression
    result := "big" if x > 10 else "small"

### For Loops

    for i in 0..5 {          // 0 to 4, exclusive
        fmt.println(i)
    }

    for i in 0..=5 {        // 0 to 5, inclusive
        fmt.println(i)
    }

    nums := []int{1, 2, 3}
    for n in nums {
        fmt.println(n)
    }

    for n, i in nums {      // Value and index
        fmt.printf("%d: %d\n", i, n)
    }

    // Traditional C-style
    for i := 0; i < 5; i += 1 {
        fmt.println(i)
    }

### While Loops

    y := 10
    for y > 0 {
        y -= 1
        fmt.println(y)
    }

    // Infinite loop
    for {
        if y <= 0 {
            break
        }
        y -= 1
    }

## Functions

    add := fn(a: int, b: int) -> int {
        return a + b
    }

    fmt.println(add(2, 3))

    // Named function
    add :: proc(a: int, b: int) -> int {
        return a + b
    }

    // Multiple return values
    divide :: proc(a: f64, b: f64) -> (f64, bool) {
        if b == 0 {
            return 0, false
        }
        return a / b, true
    }

    result, ok := divide(10.0, 2.0)
    if ok {
        fmt.println(result)
    }

    // Procedures (no return value)
    greet :: proc(name: string) {
        fmt.printf("Hello, %s!\n", name)
    }

## Arrays / Slices

### Slices

    nums: []int = [1, 2, 3]  // Slice literal, mutable and resizable
    for n in nums {
        fmt.println(n)
    }

    // Append to slice
    append(&nums, 4)
    append(&nums, 5, 6)

    // Length and capacity
    len(nums)               // Current length
    cap(nums)               // Capacity

    // Make slice with capacity
    nums := make([]int, 0, 10)  // Length 0, capacity 10

### Arrays

    arr: [3]int = {1, 2, 3}  // Fixed-size array
    arr := [3]int{1, 2, 3}   // Shorthand

    // Array size inference
    arr := [?]int{1, 2, 3}   // Compiler infers size 3

### Maps

    import "core:map"

    person := make(map[string]string)
    map.set(&person, "name", "Alice")
    map.set(&person, "age", "30")

    name, found := map.get(&person, "name")
    if found {
        fmt.println(name)
    }

    // Map literal
    person := map[string]string{
        "name" = "Alice",
        "age"  = "30",
    }

## Strings

    text := "Hello, World!"
    text := `Multiline
    string
    literal`

    // String operations
    len(text)                // Length in bytes
    fmt.printf("%s\n", text) // Print formatted

    // String concatenation
    greeting := "Hello, " + name

    // String formatting
    name := "Alice"
    greeting := fmt.tprintf("Hello, %s!", name)

## Structs

    Person :: struct {
        name: string,
        age:  int,
    }

    person := Person{
        name = "Alice",
        age  = 30,
    }

    fmt.printf("%s is %d\n", person.name, person.age)

    // Methods
    Person :: struct {
        name: string,
        age:  int,
    }

    greet :: proc(p: Person) {
        fmt.printf("Hello, I'm %s\n", p.name)
    }

    person := Person{name = "Alice", age = 30}
    greet(person)

## Enums

    Direction :: enum {
        Up,
        Down,
        Left,
        Right,
    }

    dir := Direction.Up

    switch dir {
    case .Up:
        fmt.println("Going up")
    case .Down:
        fmt.println("Going down")
    case .Left:
        fmt.println("Going left")
    case .Right:
        fmt.println("Going right")
    }

## Unions

    Value :: union {
        int,
        f64,
        string,
    }

    v: Value = 42
    v = 3.14
    v = "hello"

    switch v in v {
    case int:
        fmt.printf("Integer: %d\n", v)
    case f64:
        fmt.printf("Float: %f\n", v)
    case string:
        fmt.printf("String: %s\n", v)
    }

## Error Handling

    import "core:fmt"

    // Using optional types
    divide :: proc(a: f64, b: f64) -> (result: f64, ok: bool) {
        if b == 0 {
            return 0, false
        }
        return a / b, true
    }

    result, ok := divide(10.0, 2.0)
    if ok {
        fmt.printf("Result: %f\n", result)
    } else {
        fmt.println("Division by zero")
    }

    // Using error types
    Error :: enum {
        None,
        Division_By_Zero,
        Invalid_Input,
    }

    divide :: proc(a: f64, b: f64) -> (f64, Error) {
        if b == 0 {
            return 0, .Division_By_Zero
        }
        return a / b, .None
    }

## File Operations

    import "core:os"
    import "core:fmt"

    // Reading
    data, ok := os.read_entire_file("file.txt")
    if ok {
        fmt.println(string(data))
    }

    // Writing
    content := "Hello, World!"
    os.write_entire_file("file.txt", transmute([]u8)content)

## Memory Management

    import "core:mem"

    // Allocators
    allocator := context.allocator

    // Allocate memory
    ptr := new(int)
    ptr^ = 42

    // Free memory
    free(ptr)

    // Using different allocators
    temp_allocator := mem.temp_allocator()

## Tips

- Odin is strongly typed; type declarations are explicit.

- Loops often use ranges like `0..5` (exclusive of 5); use `0..=5` for inclusive.

- `fmt.scanf` or `read_string` can handle user input:

      import "core:fmt"
      import "core:os"

      input: [256]u8
      n, _ := os.read(os.stdin, input[:])
      text := string(input[:n])

- Slices (`[]Type`) are dynamic arrays, arrays (`[N]Type`) are fixed-size.

- Functions are first-class and can be assigned to variables.

- Use `:=` for type inference, `:` for explicit typing.

- Procedures (`proc`) are functions; use `fn` for function values.

- Multiple return values are common; use tuples or named returns.

- Use `^` to dereference pointers, `&` to take addresses.

- Odin uses explicit memory management; understand allocators for advanced usage.

- Struct literals use `=` for field assignment: `Person{name = "Alice"}`.

- Use `switch` for pattern matching on enums and unions.

- Import packages with `import "package:name"`; core library uses `"core:"` prefix.