Go泛型:无效的复合字面类型T

huangapple go评论150阅读模式
英文:

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
}

当我尝试在Go中使用泛型编码时,遇到了这个问题:

./prog.go:23:13: 无效的复合字面量类型 T

这是什么原因?有没有办法修复它?

代码链接:https://go.dev/play/p/oRiH2AyaYb6

英文:
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

答案1

得分: 3

不确定你是否需要泛型...但让我们解决一下编译错误:

invalid composite literal type T

以及关于复合字面量的Go规范:

> LiteralType的核心类型T必须是结构体、数组、切片或映射类型(除非类型以TypeName的形式给出,语法规定了这个约束)。

存在问题的代码是:

type MessageParse[T proto.Message] struct {}

func (p *MessageParse[T]) Parse(message *NetMessage) proto.Message {

    protoT := &T{} // <- 这里

泛型类型T受限于类型proto.Message。查看类型proto.Message(它是类型protoreflect.ProtoMessage的别名)可以看到它是一个Go的interface类型,而不是核心类型。因此,它不能用于实例化复合字面量。

在非泛型的示例中,你会得到相同的编译错误

type mytype interface {
	SomeMethod() error
}

_ = &mytype{}  // // ERROR: invalid composite literal type mytype
英文:

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

huangapple
  • 本文由 发表于 2022年5月7日 01:39:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/72145466.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定