gonull
is a Go package that provides type-safe handling of nullable values using generics. It's designed to work seamlessly with JSON and SQL operations, making it perfect for web services and database interactions.
- π― Type-safe nullable values using Go generics
- π‘ Omitzero support
- π Built-in JSON marshaling/unmarshaling
- π SQL database compatibility
- β¨ Zero dependencies
go get github.com/LukaGiorgadze/gonull/v2
package main
import (
"encoding/json"
"fmt"
"github.com/LukaGiorgadze/gonull"
)
type MyCustomInt int
type MyCustomFloat32 float32
type Person struct {
Name string `json:"name"`
Age gonull.Nullable[MyCustomInt] `json:"age"`
Address gonull.Nullable[string] `json:"address"`
Height gonull.Nullable[MyCustomFloat32] `json:"height"`
IsZero gonull.Nullable[bool] `json:"is_zero,omitzero"` // This property will be omitted from the output since it's not present in jsonData.
}
func main() {
jsonData := []byte(`
{
"name": "Alice",
"age": 15,
"address": null,
"height": null
}`)
var person Person
json.Unmarshal(jsonData, &person)
fmt.Printf("Unmarshalled Person: %+v\n", person)
marshalledData, _ := json.Marshal(person)
fmt.Printf("Marshalled JSON: %s\n", string(marshalledData))
// Output:
// Unmarshalled Person: {Name:Alice Age:15 Address: Height:0 IsZero:false}
// Marshalled JSON: {"name":"Alice","age":15,"address":null,"height":null}
// As you see, IsZero is not present in the output, because we used the omitzero tag introduced in go v1.24.
}
type User struct {
Name gonull.Nullable[string]
Age gonull.Nullable[int]
}
func main() {
// ...
rows, err := db.Query("SELECT id, name, age FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var user User
err := rows.Scan(&user.Name, &user.Age)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %v, Age: %v\n", user.Name.Val, user.Age.Val)
}
// ...
}