14.3 Option Types in Other Languages

Rust is not alone in providing an explicit mechanism for optional data:

  • Swift: Optional<T> for values that might be nil.
  • Kotlin: String?, Int?, etc. for nullable types.
  • Haskell: The Maybe type, with Just x or Nothing.
  • Scala: An Option type, with Some and None.

All these languages make it harder (or impossible) to forget about missing data.

14.3.1 Comparison with C’s NULL Pointers

In C, it is common to return NULL from functions to indicate ‘no result’:

#include <stdio.h>
#include <stdlib.h>

int* find_value(int* arr, size_t size, int target) {
    for (size_t i = 0; i < size; i++) {
        if (arr[i] == target) {
            return &arr[i];
        }
    }
    return NULL;
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    int* result = find_value(numbers, 5, 3);
    if (result != NULL) {
        printf("Found: %d\n", *result);
    } else {
        printf("Not found\n");
    }
    return 0;
}

Forgetting to check result before dereferencing can cause a crash. Rust’s Option<T> prevents this by forcing you to handle the None case explicitly.

14.3.2 Sentinels in C for Non-Pointer Types

When dealing with integers or other primitive types, C code often uses “magic” values (like -1) to indicate ‘not found’ or ‘unset.’ If that sentinel can appear as valid data, confusion ensues. Option<T> provides a single, consistent, and type-safe way of handling any kind of missing data.