使用仿制药时从接口中获取基本类型
我的功能无法更改,该功能看起来像foo(interface {})
。在其他类型中,此功能可以采用类型[]字节
,但不能服用[16]字节
。我想基于仿制药来编写一个小型适配器,以增加对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[:])
}
}
但是,如何将包含gofrsuuid.uuid
的接口{}
转换为该基本类型[16]字节
?
I have a function that I cannot change, the function looks like foo(interface{})
. Among some other types, this function can take a type []byte
but cannot take [16]byte
. I want to write a little adapter based on generics that add support for UUIDs instead of writing foo(uuid[:])
, but I don't want to get hung up on specific implementations. For example, instead of
import (
gofrsuuid "github.com/gofrs/uuid"
googleuuid "github.com/google/uuid"
)
type AcceptedCertainTypes interface {
int | gofrsuuid.UUID | googleuuid.UUID // | etc...
}
I want to have
type AcceptedTypes interface {
int | ~[16]byte
}
But I have no idea how to do this. When we use certain types, it is easy to turn them into the right ones.
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[:])
}
}
But how to convert interface{}
that contains gofrsuuid.UUID
to that base type [16]byte
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不能在工会的大约术语上具有详尽的类型开关,例如
〜[16]字节
,因为根据定义设置的类型是未结合的。您必须使用反射来提取阵列类型并最终重新放置它。如果大约
项
〜[16]字节
是联合联盟中唯一的一个大约项,则可以输入切口并在>默认
block中处理。这是基于类型参数的编译时类型安全性,因此默认
block不会使用任何意外类型运行:playground: https://go.dev/play/p/_uxmwgyew5n
如果联盟中有很多tilde术语
,则不能依靠<<<<<<<<<<<<<<<<<<<<<<< >默认情况案例。如果基础类型都不同,则您可以打开
Refflect.kind
:许多相似的近似术语
类型参数无济于事,只需使用
详尽地使用类型开关的所有可能类型。您可以分组您知道具有相同基础类型的类型,并使用
value#convert
,如上所示 - 或类型特定的方法,例如value#int()
或值#string()
- 以类似的方式处理它们。You can't have an exhaustive type switch on a union's approximate term like
~[16]byte
, because the type set by definition is unbound. You have to use reflection to extract the array type and eventually reslice it.Only one approximate term
If the approximate term
~[16]byte
is the only one in the union, you can type-switch and handle it in thedefault
block. This is based on the compile-time type safety of type parameters, so thatdefault
block will not run with any unexpected type:Playground: https://go.dev/play/p/_uxmWGyEW5N
Many different approximate terms
If you have many tilde terms in a union, you can't rely on
default
case. If the underlying types are all different, you may be able to switch onreflect.Kind
:Many similar approximate terms
Type parameters won't help much, just use
any
and exhaustively type-switch an all possible types. You can group types that you know have the same underlying type and useValue#Convert
as shown above — or type-specific methods likeValue#Int()
orValue#String()
—, to handle them similarly.