[英]How to write a Go type constraint for something you can take len() of?
我正在尝试为 Go 程序编写一个类型约束,它接受“任何你可以接受 len() 的东西”。 但我真的想不通。
我想要这样的东西:
LenOf[m Measurable](m M) int {
return len(m)
}
我尝试了一些东西。 外汇。 这个幼稚的东西,确实可以编译,但不适用于所有类型(比如 fx []User
):
type Measurable interface {
~string | []any | ~map[any]any
}
然后继续类似下面的事情,它不仅使LenOf()
的 function 签名非常笨拙,而且在调用站点上写起来也很笨拙(而且仍然无法编译)
type Measurable[K comparable, V any] interface {
~string | []V | ~map[K]V
}
为什么? 内置len
已经是“通用的”。
话虽如此,让我们看看为什么定义这样的约束是个坏主意。 Go 规范中有一段 — Length and capacity ,可以帮助:
如果参数类型是类型参数 P,则调用
len(e)
(或分别为cap(e)
)必须对 P 的类型集中的每个类型都有效。 结果是参数的长度(或容量),其类型对应于 P 被实例化的类型参数。
为“可测量”类型编写包罗万象的约束的问题是:
[N]T
,其中数组长度是类型的一部分,因此您的约束必须指定您要捕获的所有可能的 arrays*[N]T
,您不能在类型约束中轻易抽象它K
和值V
,它们可能与T
相同也可能不同。 另外, K
必须实现comparable
。所以你必须写这样的东西:
type Measurable[T any, K comparable, V any] interface {
~string | ~[]T | ~map[K]V | ~chan T
}
其中明显不包括 arrays,并且没有明确捕获指针文字,例如要匹配[]*int
,您必须使用*int
实例化T
您可以简化V
:
type Measurable[T any, K comparable] interface {
~string | ~[]T | ~map[K]T | ~chan T
}
function LenOf
则变为:
func LenOf[T any, K comparable, M Measurable[T, K]](m M) int {
return len(m)
}
但您仍然必须提供K
,因此您必须在呼叫站点使用 map 密钥的伪造类型实例化LenOf
:
LenOf[string, int]("foo")
// ^ actually useless
并且您也不能利用参数的类型推断。
总之:只需使用len
。 设计您的泛型函数以使用支持长度的类型字面量,或者仅将您的函数理应处理的那些类型添加到约束中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.