The way to do that is to add another level of indirection (as everything in
Software Engineering):

type Namer[T any] interface {
    *T
    SetName(name string)
}
func WithName[T any, PT Namer[T]](name string) T {
    var v T
    PT(&v).SetName(name)
    return v
}

I will say, though, that it's not unlikely that you'll be happier if you
don't do this and instead accept a plain interface value and let the caller
allocate the value and pass in a pointer. But if you want to do it, this is
the way.

On Sat, Jan 13, 2024 at 8:10 PM Daniel Theophanes <kardia...@gmail.com>
wrote:

> I have a situation where I would like to create a type, then set a
> property on it within a container. To set the type, I envisioned using a
> method "SetName" which would need to take a pointer receiver: (goplay share
> is down right now so I'll post inline:
> type Namer interface {
> SetName(name string)
> }
>
> I wish to create a new Namer type as well, ideally without using reflect.
> If I use [*Ob ] as the type parameter, that works, but then `new(T)`
> returns `**Ob`, which I can deference to get `*Ob`, but then the value is
> nil (Ob isn't created).
>
> I'm working around this, but it surprised me, the interaction of a pointer
> receiver interface type constraint and then I can't create the desired type.
>
> ```
> package main
>
> import "fmt"
>
> func main() {
> ar := NewAppResult()
> fmt.Printf("AR: %#v\n", *ar)
> ar.Observation.Get("X1")
> }
>
> type Ob struct {
> Gene  string
> Value string
> }
>
> func (o *Ob) SetName(name string) {
> // o is nil and this will panic.
> o.Gene = name
> }
>
> type Namer interface {
> SetName(name string)
> }
>
> type OrderedLookup[T Namer] struct {
> List   []T
> lookup map[string]T
> }
>
> func (ol *OrderedLookup[T]) Get(name string) T {
> v, ok := ol.lookup[name]
> if !ok {
> var v T // T is a pointer, new(T) creates **Ob, but I cant use generic
> type of [Ob] because then Namer
> v.SetName(name)
> ol.lookup[name] = v
> ol.List = append(ol.List, v)
> }
> return v
> }
>
> type AppResult struct {
> Observation *OrderedLookup[*Ob]
> }
>
> func NewAppResult() *AppResult {
> return &AppResult{
> Observation: &OrderedLookup[*Ob]{},
> }
> }
> ```
>
>
>
> --
> 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/8d0c816c-c332-4b44-87e3-9259ad173afcn%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/8d0c816c-c332-4b44-87e3-9259ad173afcn%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAEkBMfH69TQg8LndigToQyPtbmujkQr9w8Q_i80Uix5fkW2m4Q%40mail.gmail.com.

Reply via email to