假设我有一个名为foo的泛型 struct ,并从它创建了两个对象.我可以使用reflect.TypeOf()来确定每种类型的具体类型,如下所示:

package main

import (
    "fmt"
    "reflect"
)

type foo[T any] struct {
    data T
}

func main() {
    a := foo[string]{"cheese"}
    b := foo[int]{42}

    fmt.Println(reflect.TypeOf(a))
    fmt.Println(reflect.TypeOf(b))
}

// main.foo[string]
// main.foo[int]

我感兴趣的是只确定这些对象的泛型类型(即foo),而不确定具体类型(即foo[string]foo[int]).这是否可能,或者我是否需要手动从这些字符串中提取泛型类型(例如,使用正则表达式)?


编辑

Regex可能如下所示:

func GetGenericType(x any) string {
    // Get type as a string
    s := reflect.TypeOf(x).String()

    // Regex to run
    r := regexp.MustCompile(`\.(.*)\[`)

    // Return capture
    return r.FindStringSubmatch(s)[1]
}


fmt.Println(GetGenericType(a))
fmt.Println(GetGenericType(b))

// foo
// foo


我也看到了this question,但这不能回答这个问题,因为它给出的是concrete类型(即main.foo[string]),而不是泛型类型(即foo).

推荐答案

反射看不到"基"泛型类型的名称,因为在运行时该基类型不存在.

围棋规范中的相关段落是Instantiations:

实例化一个类型会得到new non-generic named type;实例化函数会产生一个新的非泛型函数.

所以当你写的时候:

b := foo[int]{42}
name := reflect.TypeOf(b).Name()

这种类型的名称恰好是foo[int].

值得注意的是,不带类型参数列表的identifier foo在编译时是相关的,因为它防止您在同一个包中重新声明它.Type definitions:

类型定义创建具有相同类型的新的不同类型 基础类型和操作作为给定类型和binds an identifier, the type name, to it.

TypeDef = identifier [ TypeParameters ] Type .

但如上所述,实例化会产生一个不同于foo的新命名类型;在可以使用反射的运行时,您只能处理实例化.

总之,我认为您使用正则表达式的解决方案是可以接受的,除非在stdlib中添加一些helper函数(如果有的话).

请记住Type.String()Type.Name()之间的区别:任何类型都可以有字符串表示,但只有命名类型才有名称.(显然,对吧?)因此,例如,如果您写道:

b := &foo[int]{42}

b的类型是*foo[int],这是一个匿名复合类型,Name()返回空字符串.

Go相关问答推荐

如何在定制普罗米修斯出口商中测试动态计量注册?

调用API时使用nginx作为反向代理时从nginx获取502坏网关

Golang应用程序:所请求的资源上不存在HTTP-Control-Allow-Origin标头

带有条件的for循环中缺少RETURN语句

在Uber FX中实现后台进程正常关闭的正确方式是什么?

错误&对象已被Golang在K8s操作符上修改

Golang内置打印(Ln)函数&S行为怪异

包裹网.Conn导致挂起读取

Go 是否提供了标准或事实上的方法来处理单个语句中的错误(即内联错误处理)?

这是go语言gin提供的关于TypeEngine和RouterGroup的问题

Go 中将 int 切片转换为自定义 int 切片指针类型的函数

我可以扫描表中每个项目的最高范围键值吗?

Go time.Parse 无效的 ISO 日期

如何从 Go 中的 `HijackedResponse` 中删除 Cursor Position ANSI 转义码?

go-echo中如何防止+转义

如何在切片增长时自动将切片的新元素添加到函数参数

如何在golang中按字符a对字符串数组进行排序

使用 Golang SQL 驱动程序连接到snowflake

有没有办法在golang中映射一组对象?

Golang 泛型同时具有接口和实现