Generics - is there an equivalent to Rust "Self" type

Rust generic has a “Self” which is the Concrete type of the instantiated Generic type. Is there an equivalent in Go?

Specifically, so i can get Clone() to return a Self. Then i can have generic struct which will implement the Clone interface.

Something like,

type Cloner[T any] interface {
    Clone() T
}

type Parent[T any] struct {
    parentAttr T
    Cloner[Self] 
}

func (p Parent[T]) Clone() Parent[T] {  return a clone of the parent obj }

type Child[T any] struct {
   Parent[T]
   childAttr string
}

func (c Child[T]) Clone() Child[T] { return a clone of the child obj }

Hi @globalflea,

It is indeed possible that an interface method’s argument refers to the interface type - see this article for details:

How to use generics for creating self-referring interfaces

TL;DR:

Step 1. The Cloner interface stays unchanged.

type Cloner[C any] interface {
	Clone() C
}

C is not restricted to anything yet, but step 2 takes care of this.

Step 2. A function that clones any type uses Cloner[T] as type restriction:

func CloneAny[T Cloner[T]](c T) T {
	return c.Clone()
}

Then, for any variable s whose type implements Cloner, you can simply call

CloneAny(s)

to clone s.

Playground link

The blog article explains this solution in more detail.

Thanks.

Hi Christoph,

thank you for your blog post.

You use this snippet in the post:

cloned := CloneAny(s)
if cs, ok := cloned.(CloneableSlice); ok {
    fmt.Println(cs[3])
}

Why not use cloned := s.Clone() and make every Clone-method return the particular type?

Then you don’t need a type assertion.

Hi @guettli,

Because then the Clone methods would not implement the Cloner interface.

Your solution is of course perfectly fine if a Cloner interface is not required. Always use the simplest solution possible!