Golang中泛型的理解与探讨

Golang中泛型的理解与探讨

package main

import "fmt"

type Container[T any] struct {
	Data []T
}

func (c Container[T]) Filter(f func(T) bool) Container[T] {
	var r Container[T]

	for _, i := range c.Data {
		if f(i) {
			r.Data = append(r.Data, i)
		}
	}

	return r
}

func main() {
	intContainer := Container[int]{
		Data: []int{1, 2, 3, 4, 5},
	}

	fmt.Println(intContainer.Filter(func(v int) bool { return v < 4 }))
}

我本以为上面的代码能正常工作,但我遇到了以下错误:

./main.go:13:8: cannot use i (variable of type int) as type T in argument to f
./main.go:14:28: cannot use i (variable of type int) as type T in argument to append

我不明白为什么。既然我用 T 作为 int 来初始化容器,我期望接收器函数也期望 Tint 类型?那么为什么这不起作用呢?

[编辑] 没关系……我忘记了我循环遍历切片时得到的是索引和值。所以我是在用 int(键)而不是值 T 来操作。我之所以没注意到这一点,是因为即使我解决了这个问题,Goland 仍然在抱怨代码。但上面的例子现在可以工作了。


更多关于Golang中泛型的理解与探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中泛型的理解与探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go的泛型实现中,类型参数T在方法内部会被正确实例化。你遇到的错误确实是因为循环变量使用不当。修正后的代码应该使用值而不是索引:

package main

import "fmt"

type Container[T any] struct {
	Data []T
}

func (c Container[T]) Filter(f func(T) bool) Container[T] {
	var r Container[T]
	
	for _, v := range c.Data {  // 使用值v而不是索引i
		if f(v) {
			r.Data = append(r.Data, v)
		}
	}
	
	return r
}

func main() {
	intContainer := Container[int]{
		Data: []int{1, 2, 3, 4, 5},
	}
	
	result := intContainer.Filter(func(v int) bool { return v < 4 })
	fmt.Println(result.Data)  // 输出: [1 2 3]
}

Container[int]被实例化时,Filter方法中的T会被替换为int类型。在循环中,v的类型就是int,与函数参数f func(T) bool中的T类型匹配。

泛型方法的类型参数实例化是编译时完成的。对于Container[int]实例,编译器会生成一个Filter方法,其中所有T都被替换为int。这意味着方法调用intContainer.Filter(func(v int) bool)中的函数签名与实例化后的方法签名完全匹配。

如果IDE仍然报错,可能是缓存或索引问题。可以尝试清理IDE缓存或重启IDE。编译器和go工具链应该能正确处理这段代码。

回到顶部