Search code examples
gogenericscomposite-literals

Go generics: invalid composite literal type T


package main

import (
    "google.golang.org/protobuf/proto"
)

type NetMessage struct {
    Data []byte
}

type Route struct {
}

type AbstractParse interface {
    Parse(*NetMessage) proto.Message
}

type MessageParse[T proto.Message] struct {
}

func (p *MessageParse[T]) Parse(message *NetMessage) proto.Message {
    protoT := &T{}
    if len(message.Data) > 0 {
        err := proto.Unmarshal(message.Data, protoT)
        if err != nil {
            return nil
        }
    }

    return protoT
}

When I tried generic coding for Go, I encountered this problem:

./prog.go:23:13: invalid composite literal type T

What was the cause? Is there any way to fix it?

code link: https://go.dev/play/p/oRiH2AyaYb6


Solution

  • Not sure you need Generics... but let's address your compilation error:

    invalid composite literal type T
    

    and the Go spec regarding composite literal:

    The LiteralType's core type T must be a struct, array, slice, or map type (the grammar enforces this constraint except when the type is given as a TypeName).

    The code at issues is:

    type MessageParse[T proto.Message] struct {}
    
    func (p *MessageParse[T]) Parse(message *NetMessage) proto.Message {
    
        protoT := &T{} // <- here
    

    The generic type T is constrained on the type proto.Message. Looking at type proto.Message (which is an alias for type protoreflect.ProtoMessage) shows it is a Go interface type and NOT a core type. Thus it cannot be used to instantiate a composite literal.

    You would get the same compilation error in a non-Generics example like:

    type mytype interface {
        SomeMethod() error
    }
    
    _ = &mytype{}  // // ERROR: invalid composite literal type mytype