hi,
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