Go言語にはGenericsが実装されて以降に作られた samber/lo というライブラリがある。
これはLodashぽく使えるライブラリで、Go言語のGenericsを使っている。

このライブラリを使っていて、lo.IfをJavaScriptの三項演算子みたいに使おうとしたらハマったのでメモ。

lo.If は以下のように使うことができる。

result := lo.If(true, 1).
    ElseIf(false, 2).
    Else(3)
// 1

result := lo.If(false, 1).
    ElseIf(true, 2).
    Else(3)
// 2

result := lo.If(false, 1).
    ElseIf(false, 2).
    Else(3)

定義としては

func If[T any](condition bool, result T) *ifElse[T]

となっている。

第一引数に真偽値、第二引数に結果を渡すと、ifのように使える。

なので次のように使うと三項演算子みたいに使えて1行で書け便利そうと思っていた。

package main

import (
	"fmt"

	"github.com/samber/lo"
)

func main() {
	var in *int

	fmt.Println(lo.If(in == nil, *in).Else(0))
}

実装内容としては、innilの場合は0を返し、それ以外の場合は*inを返すというもの。
この実装はinnilの場合にpanicを起こす。
inの内容はnilだろうがそうじゃなかろうが必ず評価されるからである。
まぁ、よく見たら当然といえば当然である。

今回やりたいことはnilじゃないときは値を返してそうじゃないときはデフォルト値を返すというものにしたかった。
なので次のような関数を用意することにした。

func ToValue[T any](in *T, def T) T {
	if in == nil {
		return def
	}
	return *in
}