为了账号安全,请及时绑定邮箱和手机立即绑定

使用泛型时从接口获取基类型

使用泛型时从接口获取基类型

Go
慕村9548890 2022-12-19 17:53:41
我有一个我无法更改的功能,该功能看起来像foo(interface{}). 在其他一些类型中,此函数可以采用类型[]byte但不能采用[16]byte. 我想写一个基于泛型的小适配器来添加对 UUID 的支持而不是编写foo(uuid[:]). 但我不想挂在特定的实现上。例如,而不是import (    gofrsuuid "github.com/gofrs/uuid"    googleuuid "github.com/google/uuid")type AcceptedCertainTypes interface {    int | gofrsuuid.UUID | googleuuid.UUID // | etc...}我希望有type AcceptedTypes interface {    int | ~[16]byte}但我不知道该怎么做。当我们使用某些类型时,很容易将它们变成正确的类型。func rewrittenFoo[T AcceptedCertainTypes](val T) {    var t interface{} = *new(T)    switch t.(type) {    case gofrsuuid.UUID:        k := val.(gofrsuuid.UUID)        foo(k[:])    case googleuuid.UUID:        k := val.(googleuuid.UUID)        foo(k[:])    }}但是如何将interface{}contains转换gofrsuuid.UUID为该基本类型[16]byte?
查看完整描述

1 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

您不能对联合的近似项(如 )进行详尽的类型转换~[16]byte,因为定义设置的类型是未绑定的。您必须使用反射来提取数组类型并最终将其重新切片。


只有一个近似项

如果近似项~[16]byte在联合中是唯一的,你可以在default块中进行类型转换和处理。这是基于类型参数的编译时类型安全性,因此该default块不会以任何意外类型运行:


func rewrittenFoo[T int | ~[16]byte](val T) {

    switch t := any(val).(type) {

    // handle all non-approximate type cases first

    case int:

        foo(t) // t is int


    // this will be all other types in T's type set that are not int

    // so effectively ~[16]byte

    default:

        v := reflect.ValueOf(t).Convert(reflect.TypeOf([16]byte{})).Interface().([16]byte)

        foo(v[:])

    }

}

游乐场:https ://go.dev/play/p/_uxmWGyEW5N


许多不同的近似项

如果联合中有很多代字号,则不能依赖default大小写。如果底层类型都不同,您可以打开reflect.Kind:


func rewrittenFoo[T int | ~float64 | ~[16]byte](val T) {

    // handle all non-approximate type cases first

    switch t := any(val).(type) {

    case int:

        foo(t)

    }


    switch reflect.TypeOf(val).Kind() {

    case reflect.Float:

        // ...


    case reflect.Array:

        // ...

    }

}

许多相似的近似项

类型参数不会有太大帮助,只需使用any并详尽地类型切换所有可能的类型。您可以将您知道具有相同基础类型的类型分组,并使用Value#Convert如上所示 - 或特定于类型的方法(如Value#Int()或Value#String()-)来类似地处理它们。


查看完整回答
反对 回复 2022-12-19
  • 1 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信