JS
GO

JavaScript to Go

10 lessons

Progress0%
1Variables & Types2Functions3Objects → Structs4Async → Goroutines5Errors & Panic6Interfaces7Slices and Maps8Packages and Modules9Testing10Standard Library
All Mirror Courses
JS
GO
Slices and Maps
MirrorLesson 7 of 10
Lesson 7

Slices and Maps

Go's dynamic arrays and hash maps

Introduction

In this lesson, you'll learn about slices and maps in Go. Coming from JavaScript, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.

Mirror Card
JS
From JavaScript:

In JavaScript, you're familiar with go's dynamic arrays and hash maps.

GO
In Go:

Go has its own approach to go's dynamic arrays and hash maps, which we'll explore step by step.

The Go Way

Let's see how Go handles this concept. Here's a typical example:

GO
Go Example
package main

import (
    "fmt"
    "sort"
)

func main() {
    // Slice — dynamic array
    nums := []int{1, 2, 3}
    nums  = append(nums, 4)         // [1 2 3 4]
    fmt.Println(len(nums))          // 4
    fmt.Println(nums[1:3])          // [2 3]
    sub := nums[1:3]                // slice (shares memory!)

    // make with capacity
    s := make([]int, 0, 10)        // len=0, cap=10
    s  = append(s, 1, 2, 3)

    // copy (independent)
    dst := make([]int, len(nums))
    copy(dst, nums)

    // Sort
    sort.Ints(nums)
    sort.Slice(nums, func(i,j int) bool { return nums[i] < nums[j] })

    // Map
    m := map[string]int{"a": 1}
    m["b"] = 2
    val, ok := m["a"]              // safe get; ok=false if missing
    delete(m, "a")
    fmt.Println(len(m))

    // Iterate
    for k, v := range m    { fmt.Println(k, v) }
    for i, v := range nums { fmt.Println(i, v) }
}

Comparing to JavaScript

Here's how you might have written similar code in JavaScript:

JS
JavaScript (What you know)
// Array
const nums = [1, 2, 3];
nums.push(4);          // [1,2,3,4]
nums.length;           // 4
nums.slice(1, 3);      // [2,3]
nums.includes(2);      // true
nums.sort((a,b)=>a-b);

// Map
const m = new Map();
m.set("a", 1);
m.get("a");            // 1
m.has("a");            // true
m.delete("a");
m.size;

// Iterate
for (const [k,v] of m) { console.log(k,v); }
for (const x of nums)  { console.log(x); }
Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

append() returns a new slice — always reassign: s = append(s, x)

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

Slices share underlying array — use copy() for independent copies

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

make([]T, len, cap) pre-allocates capacity for performance

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

Map lookup returns (value, ok) — always check ok to distinguish missing from zero value

Mirror Card
JS
From JavaScript:

You may be used to different syntax or behavior.

GO
In Go:

delete(m, key) removes; len(m) for size; range m iterates

Step-by-Step Breakdown

1. Slices vs Arrays

Go arrays have fixed size ([3]int). Slices are dynamic views over arrays. Use slices in practice; arrays are rarely used directly.

JS
JavaScript
const nums = [1, 2, 3]; nums.push(4);
GO
Go
nums := []int{1, 2, 3}   // slice literal
nums = append(nums, 4)   // always reassign!
Common Pitfall
Forgetting to reassign after append is a common Go bug: append(nums, 4) without = changes nothing.

2. Slice Sharing

Slices share the underlying array. Modifying a sub-slice modifies the original. Use copy() when you need independence.

JS
JavaScript
const copy = [...arr]; // spread makes new array
GO
Go
sub := nums[1:3]          // shares memory
dst := make([]int, len(nums))
copy(dst, nums)           // truly independent

3. Map Safe Access

Map access in Go returns the zero value for missing keys — no undefined, no panic. Use the two-value form to distinguish zero from missing.

JS
JavaScript
const v = m.get("key") ?? "default";
GO
Go
if val, ok := m["key"]; ok {
    // key exists
} else {
    // key missing; val is zero value
}

4. range Keyword

range iterates slices (index, value) and maps (key, value). Use _ to discard unwanted variables.

JS
JavaScript
for (const [i, v] of nums.entries()) { ... }
for (const [k, v] of map) { ... }
GO
Go
for i, v := range nums { fmt.Println(i, v) }
for k, v := range m   { fmt.Println(k, v) }
for _, v := range nums { fmt.Println(v) } // discard index

Common Mistakes

When coming from JavaScript, developers often make these mistakes:

  • append() returns a new slice — always reassign: s = append(s, x)
  • Slices share underlying array — use copy() for independent copies
  • make([]T, len, cap) pre-allocates capacity for performance
Common Pitfall
Don't assume Go works exactly like JavaScript. While the concepts may be similar, the syntax and behavior can differ significantly.

Key Takeaways

  • append returns new slice — always reassign: s = append(s, item)
  • Slices share memory; copy(dst, src) for independent copies
  • Map lookup: val, ok := m[key] — check ok to test key existence
  • range for loops give (index, value) for slices, (key, value) for maps
Rule of Thumb
The best way to learn is by doing. Try rewriting some of your JavaScript code in Go to practice these concepts.
PreviousNext