Home > Back-end >  What is the dereference operator of a type in Go generics?
What is the dereference operator of a type in Go generics?

Time:01-25

When doing generics, one can create a pointer type from any type, see Pointer Method Example section in Types Parameter Proposal. Example:

type Pointer[T any] interface {
    *T // non-interface type constraint element
    // ... more constraints ...
}

How does one do the opposite, declare a dereference of a type ? Something like:

type Deref[T any] interface {
   ???T  // If T=="*int", this would refer to "int"
   ...
}

Thanks!

CodePudding user response:

You can only dereference pointer vaues, but not types. *T is not dereferencing the T type, *T is a type literal, composing a pointer type whose base type will be T.

The compiler only allows operations on values of type parameters that are allowed on the constrained types.

Using any, all types will be allowed, even non-pointer types, whose values cannot be dereferenced.

To dereference a value, it must be a pointer. One way is to specify a parameter to be of type *T like in this example:

func deref[T any](p *T) T {
    return *p
}

T can be of any type, but *T will surely be a pointer type, whose values can be dereferenced. Testing it:

p := &image.Point{1, 2}
x := deref(p)
log.Printf("%T %v\n", x, x)

p := new(int)
*p = 3
x := deref(p)
log.Printf("%T %v\n", x, x)

Output will be:

2009/11/10 23:00:00 image.Point (1,2)
2009/11/10 23:00:00 int 3

Another option is to use a constraint that allows only pointer types, for example only *int:

func deref2[T interface{ *int }](p T) {
    log.Printf("%T %v\n", *p, *p)
}

Testing it:

p := new(int)
*p = 4
deref2(p)

Output:

2009/11/10 23:00:00 int 4

Although using generics here has no use, you could just substitute T with *int, without type parameters.

Try the examples on the Go Playground.

CodePudding user response:

There is no such thing as a "dereference of a type".

Pointer types are composite types, i.e. you need a base type to begin with. You can't go the other way around.

If you want to force non-pointer types in a constraint, specify the non-pointer types:

// will disallow *int
type NonPointerInt interface {
    ~int
}

However this is not generalizable to any T. With any constraint you could pass types like int (base type) itself or ***int (pointer to pointer to pointer to...) and then this hypothetical "type dereference" would have unclear meaning.

  •  Tags:  
  • Related