Home > Back-end >  Method on struct with generic variable
Method on struct with generic variable

Time:04-22

I have following code that uses generics. I know that one can't use generics with methods, but can with types. Technically, my code complies with both restrictions, but still I get en error

./main.go:12:9: cannot use generic type GenericCacheWrapper[T any] without instantiation

The instantiation is on the first line of main function. Is there any way to achieve this? May this be considered a Golang bug?


import (
    "encoding/json"
    "fmt"
)

type GenericCacheWrapper[T any] struct {
    Container T
}

func (c GenericCacheWrapper) MarshalBinary() (data []byte, err error) {
    return json.Marshal(c.Container)
}

func (c GenericCacheWrapper) UnmarshalBinary(data []byte) error {
    return json.Unmarshal(data, &c.Container)
}

func main() {
    wrapper := GenericCacheWrapper[int]{Container: 4}
    data, err := wrapper.MarshalBinary()
    if err != nil {
        panic(err)
    }

    fmt.Println(data)
}

https://go.dev/play/p/9sWxXYmAcUH

CodePudding user response:

You just have to add [T] to the end of GenericCacheWrapper or [_] if you want to make it clear that you are not actually using T in the functions.

package main

import (
    "encoding/json"
    "fmt"
)

type GenericCacheWrapper[T any] struct {
    Container T
}

func (c GenericCacheWrapper[T]) MarshalBinary() (data []byte, err error) {
    return json.Marshal(c.Container)
}

func (c GenericCacheWrapper[T]) UnmarshalBinary(data []byte) error {
    return json.Unmarshal(data, &c.Container)
}

func main() {
    wrapper := GenericCacheWrapper[int]{Container: 4}
    data, err := wrapper.MarshalBinary()
    if err != nil {
        panic(err)
    }

    fmt.Println(data)
}

This rule is defined in the language spec:

A generic type may also have methods associated with it. In this case, the method receivers must declare the same number of type parameters as present in the generic type definition.

But the reason behind this isn't very clear, perhaps to make implementation of the compiler/type checking easier.

Related: Go error: cannot use generic type without instantiation

  • Related