Skip to content

Instantly share code, notes, and snippets.

@DylanSp
Last active July 5, 2022 13:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DylanSp/e5e2d6c557e70ced9e1fefe0c0cd353c to your computer and use it in GitHub Desktop.
Save DylanSp/e5e2d6c557e70ced9e1fefe0c0cd353c to your computer and use it in GitHub Desktop.
Option type in Go as a struct with a boolean flag
package main
import (
"fmt"
)
// begin Option package
type Option[T any] struct {
hasValue bool
value T
}
func None[T any]() Option[T] {
return Option[T]{
hasValue: false,
}
}
func Some[T any](t T) Option[T] {
return Option[T]{
hasValue: true,
value: t,
}
}
func (opt Option[T]) Destructure(noneCase func(), someCase func(T)) {
if opt.hasValue {
someCase(opt.value)
} else {
noneCase()
}
}
// end option package
func printValueOrDefault(optStr Option[string]) {
defaultStr := "default"
optStr.Destructure(func() {
fmt.Println(defaultStr)
}, func(str string) {
fmt.Println(str)
})
}
func main() {
noneStr := None[string]()
someStr := Some("hello!")
printValueOrDefault(noneStr)
printValueOrDefault(someStr)
}
@DylanSp
Copy link
Author

DylanSp commented Jun 30, 2022

Methods can't have type parameters, even when the receiver is a struct type instead of an interface.

func (opt Option[T]) Map[U any](mapper func(T) U) Option[U] {
}

gives a compiler error method must have no type parameters.

@DylanSp
Copy link
Author

DylanSp commented Jun 30, 2022

Map() as standalone function:

func Map[T any, U any](opt Option[T], mapper func(T) U) Option[U] {
	if !opt.hasValue {
		return None[U]()
	}

	mappedVal := mapper(opt.value)
	return Some(mappedVal)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment