Enhancing Golang with Scala-Style Option Handling for Safer Code

As a developer and a fan of Scala and functional languages I really like to have an ability to be able to handle optional or nullable objects safely and be able to chain them to something new. Standard way to handle them in Golang is to handle them iteratively. For example:

type Customer struct {
    firstName string
    car *Car // customer might have a car
}

type Car struct {
    plateNumber string
}

func getCustomerPlateNumber(customer Customer) *string {
    if customer.car != nil {
        return &customer.car.plateNumber
    }
    return nil
}

To make code more readable, especially if we have to deal with a chain of optional values, I made a library https://github.com/martianoff/go-option that uses functional language patterns and follows syntax of Scala Option

import "github.com/martianoff/go-option"

type Customer struct {
    firstName string
    car option.Option[Car] // customer might have a car
}

type Car struct {
    plateNumber string
}

func getCustomerPlateNumber(customer Customer) option.Option[string] {
    return option.Map(customer.car, func(car Car) string {
        return car.plateNumber
    })
}

Features of the package:

  • Safe Handling of Missing Values: The Option[T] type encourages safer handling of missing values, avoiding null pointer dereferences. It can be checked for its state (whether it's Some or None) before usage, ensuring that no nil value is being accessed.

  • Functional Methods: The module provides functional methods such as Map, FlatMap etc. that make operations on Option[T] type instances easy, clear, and less error-prone.

  • Pattern Matching: The Match function allows for clean and efficient handling of Option[T] instances. Depending on whether the Option[T] is Some or None, corresponding function passed to Match get executed, which makes the code expressive and maintains safety.

  • Equality Check: The Equal method provides an efficient way to compare two Option[T] instances, checking if they represent the same state and hold equal values.

  • Generics-Based: With Generics introduced in Go, the module offers a powerful, type-safe alternative to previous ways of handling optional values.

  • Json serialization and deserialization: Build-in Json support

By leveraging functional language patterns, developers can handle optional or nullable objects more effectively, reducing the risk of null pointer dereferences.

0
Subscribe to my newsletter

Read articles from Maksim Martianov directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Maksim Martianov
Maksim Martianov

Senior Software Engineer at Snowflake. Expert in scalable architecture, cloud tech, and security. Passionate problem-solver and mentor.