C
GO

C to Go

10 lessons

Progress0%
1Variables & Types2Functions3Arrays & Slices4Structs & Methods5Pointers6Concurrency7Header Files → Packages8Error Handling9Testing10Standard Library
All Mirror Courses
C
GO
Arrays & Slices
MirrorLesson 3 of 10
Lesson 3

Arrays & Slices

Sequence data structures

Introduction

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

Mirror Card
C
From C:

In C, you're familiar with sequence data structures.

GO
In Go:

Go has its own approach to sequence data structures, 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"

func main() {
    // Fixed array (rarely used directly)
    var nums [5]int = [5]int{1, 2, 3, 4, 5}

    // Slice — dynamic, the idiomatic way
    s := []int{1, 2, 3, 4, 5}
    s = append(s, 6)          // grow
    s2 := append(s, 7, 8, 9) // chain

    sub := s[1:4] // slice of slice [2,3,4]

    fmt.Println(len(s), cap(s))

    // make for pre-allocated slices
    big := make([]int, 10, 100) // len=10, cap=100

    // Pass slice — no need for length param
    printSlice(s)
}

func printSlice(s []int) {
    for _, v := range s {
        fmt.Println(v)
    }
}

Comparing to C

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

C
C (What you know)
#include <stdio.h>
#include <stdlib.h>

/* Fixed-size array */
int nums[5] = {1, 2, 3, 4, 5};
int n = sizeof(nums)/sizeof(nums[0]);

/* Dynamic array */
int *dyn = malloc(5 * sizeof(int));
dyn[0] = 10;
/* ... fill ... */
dyn = realloc(dyn, 10 * sizeof(int));
free(dyn);

/* Pass array to function — pointer + length */
void printArr(int *arr, int len) {
    for (int i = 0; i < len; i++)
        printf("%d ", arr[i]);
    printf("\n");
}
Mirror Card
C
From C:

You may be used to different syntax or behavior.

GO
In Go:

Go slices are dynamic and garbage-collected; C dynamic arrays need malloc/free

Mirror Card
C
From C:

You may be used to different syntax or behavior.

GO
In Go:

Go slices carry their length — no need to pass length as separate param

Mirror Card
C
From C:

You may be used to different syntax or behavior.

GO
In Go:

append() in Go replaces realloc(); no manual size tracking

Mirror Card
C
From C:

You may be used to different syntax or behavior.

GO
In Go:

Go's range replaces C's for(i=0; i<n; i++) pattern

Step-by-Step Breakdown

1. Slices vs Arrays

Go arrays are fixed-size and rarely used directly. Slices are the idiomatic Go collection — dynamic, length-aware, and garbage-collected.

C
C
int arr[5] = {1, 2, 3, 4, 5};
GO
Go
s := []int{1, 2, 3, 4, 5} // slice, not array

2. append vs realloc

Go's append automatically grows the backing array when needed, replacing the error-prone realloc pattern.

C
C
dyn = realloc(dyn, new_size * sizeof(int));
GO
Go
s = append(s, newElement)

3. Slices as Parameters

Go slices include their length, so you never need a separate length parameter. The called function can use len() directly.

C
C
void printArr(int *arr, int len) { ... }
GO
Go
func printSlice(s []int) {
    fmt.Println(len(s)) // length built-in
}

Common Mistakes

When coming from C, developers often make these mistakes:

  • Go slices are dynamic and garbage-collected; C dynamic arrays need malloc/free
  • Go slices carry their length — no need to pass length as separate param
  • append() in Go replaces realloc(); no manual size tracking
Common Pitfall
Don't assume Go works exactly like C. While the concepts may be similar, the syntax and behavior can differ significantly.

Key Takeaways

  • Go slices replace C's manual dynamic arrays
  • append() replaces malloc/realloc
  • Slices carry their length — no extra parameter needed
  • range replaces C's index-based for loops
Rule of Thumb
The best way to learn is by doing. Try rewriting some of your C code in Go to practice these concepts.
PreviousNext