关于在方法的receiver中使用泛型的问题
话不多说,直接贴代码
func main() {
var a MySlice[string]
a = append(a, "2")
v := a.Sum()
fmt.Println(v)
}
type MySlice[T int | float32 | string] []T
func (s MySlice[string]) Sum() int {
var res int
for _, v := range s {
conv, _ := strconv.Atoi(v)
res = res + conv
}
return res
}
问题:
在方法Sum()
的receiver (s MySlice[string])
中,把泛型类型 MySlice
中的 T
约束为 string
。
此时在 for _, v := range s
中, v
的类型应该是 string
。 但是在 conv, _ := strconv.Atoi(v)
中会编译错误:
cannot use v (variable of type string constrained by int|float32|string) as type string in argument to strconv.Atoi
这是为什么呢? 难道在方法receiver中的类型不是这样用的吗? 有没有更好的例子可以解释如何正确在方法receiver中使用泛型?
我编辑了一下代码,发现好像在 receiver 中并不会对泛型起到约束作用…
func main() {
var a MySlice[int]
a = append(a, 1)
v := a.Sum()
fmt.Println(v)
}
type MySlice[T int | float32 | string] []T
func (s MySlice[string]) Sum() int {
var res int
for _, v := range s {
fmt.Printf("%T\n", v)
}
return res
}
这里输出出来, for _, v := range s
中 v
的类型是 int
。
那么receiver里的 s MySlice[string]
感觉其实是没有任何用处呀
再来一个有趣的现象:
func main() {
var a MySlice[string]
a = append(a, "2", "3")
v := a.Sum()
fmt.Println(v)
fmt.Printf("%T\n", v)
}
type MySlice[T int | float32 | string] []T
func (s MySlice[int]) Sum() int {
var res int
for _, v := range s {
res = res + v
}
return res
}
我写完这个代码,以为输出的内容是:
5
int
结果实际执行结果是:
23
string
类型约束 和 类型参数 不能写在一起
正确做法