guregu / null

reasonable handling of nullable values
BSD 2-Clause "Simplified" License
1.86k stars 238 forks source link

Generics support #67

Closed guregu closed 8 months ago

guregu commented 3 years ago

Any ideas or opinions on how to handle generics in this library? I played around with creating a generic Null[T] type, but I wonder if it's even useful at that point, because we are essentially recreating the Optional type you might find in other languages. At what point is it going too far? Maybe ideally we could make generic Null/Zero types and use the materialized version of it for each pre-existing type.

I'm also curious if we'll see a generic sql.Null[T] type in the standard library, which might obsolete a good chunk of this library, especially if this change lands: https://github.com/golang/go/issues/5901 (which lets you easily specify custom marshalers for JSON, moving the responsibility from the object itself to the encoding site).

See also: https://github.com/golang/go/issues/48702

lucklo commented 2 years ago

I think it's matter of time for community to be able to share useful feedback. Until 1.18 become stable I would suspect we wont have good perspective. I think it wouldnt be a bad idea to create a new feature branch with "generics proposal". It's like testing new hammer design :)

jinoos commented 2 years ago

Interesting! :)

guregu commented 1 year ago

Looks like we will have an official generic sql.Null[T] in Go 1.22: https://github.com/golang/go/issues/60370 Should (hopefully) be possible to wrap it in a nice way, although I'm not sure about the logistics around converting the data within.

LukaGiorgadze commented 1 year ago

Hi guys, here's the implementation of go null with generics: https://github.com/lomsa-dev/gonull supports custom types.

usage:

package main

import (
    "encoding/json"
    "fmt"

    "github.com/lomsa-dev/gonull"
)

type MyCustomInt int
type MyCustomFloat32 float32

type Person struct {
    Name    string
    Age     gonull.Nullable[MyCustomInt]
    Address gonull.Nullable[string]
    Height  gonull.Nullable[MyCustomFloat32]
}

func main() {
    jsonData := []byte(`{"Name":"Alice","Age":15,"Address":null,"Height":null}`)

    var person Person
    err := json.Unmarshal(jsonData, &person)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Unmarshalled Person: %+v\n", person)

    marshalledData, err := json.Marshal(person)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Marshalled JSON: %s\n", string(marshalledData))
}
cspeidel commented 8 months ago

Looks like we will have an official generic sql.Null[T] in Go 1.22: golang/go#60370 Should (hopefully) be possible to wrap it in a nice way, although I'm not sure about the logistics around converting the data within.

sql.Null[T] has landed. https://github.com/golang/go/issues/60370 https://go.dev/doc/go1.22

guregu commented 8 months ago

Nice, I will look into a new release that includes support for that and the other types we're missing from the stdlib like uint

guregu commented 8 months ago

Released in v5 https://github.com/guregu/null/releases/tag/v5.0.0 This is a minimal wrapper around sql.Null[T] In general it's impossible to support TextMarshaler for everything so it omits that Feel free to make an issue if you have any ideas/suggestions