hi,

On Fri Apr 15, 2022 at 08:00 CET, Zhaoxun Yan wrote:
> Here is my note on json & struct, run it somewhere and it may give you a
> hint.
>
> package main
>
> import "fmt"
> import "encoding/json"
>
> type prices struct{
> Price float64 `json:"price"`
> floor float64
> Ceiling float64
> settle float64
> time int64
> }
>
>
> func main() {
> content := prices{
> Price: 6.4 ,
> floor: 3.5,
> Ceiling: 7,
> settle: 8.5,
> time: 1,
> }
>     
> js,_ := json.Marshal( content)
> fmt.Println(string(js))
>
> var back prices
> json.Unmarshal(js, &back)
> fmt.Println(back)
> fmt.Println(back.Price)
> }

thanks for the offer.
but that's not really what I am after.

my issue is two-fold:
- how to convey the constraint of the Unmarshaler interface (which is
  logically implemented on a pointer receiver, so *T, not T)
- how to create values of T (where *T implements Unmarshaler)

I have managed to something along these lines, with some reflect help:

https://go.dev/play/p/-CK2Bk-LU8y

```
type T1 struct {
        v string
}

func (t *T1) Unmarshal(p []byte) error {
        t.v = string(p)
        return nil
}

type Unmarshaler interface {
        Unmarshal(p []byte) error
}

func f[T Unmarshaler]() T {
        t := alloc[T]()
        unmarshal(t)
        return t
}

func alloc[T any]() T {
        var t T
        rv := reflect.ValueOf(&t).Elem()
        rv.Set(reflect.New(rv.Type().Elem()))
        return t
}

func unmarshal[T Unmarshaler](t T) {
        err := t.Unmarshal([]byte("hello"))
        if err != nil {
                panic(err)
        }
}

func main() {
        t := *f[*T1]()
        log.Printf("t1: %+v", t)
}
```

so: passing *T to the "factory function", and using reflect to reach
into the guts of underlying type, allocate and return the newly
populated value.

it's not super robust.
but I can do.

perhaps I am not holding it right?
I am probably missing the type manipulation vocabulary (akin to
reflect's PointerTo and Elem/Indirect facilities).

-s

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CJAO04K8C1DK.18Q28RHGMJLD9%40clrinfopc42.

Reply via email to