Golang中使用泛型实现多态Clone()方法?
Golang中使用泛型实现多态Clone()方法?
尝试创建一个 Clone() 函数,该函数返回“最终”的具体类型,并使用引用以多态方式创建最终类型的克隆,但遇到了编译错误。欢迎提供想法/解决方案。
是否有可能使下面的代码编译通过,或者是否有惯用的方法来实现带有接口/结构体嵌入的多态克隆?
package main
import "fmt"
type Cloner[T any] interface {
Clone() T
}
type AI[T any] interface {
// 希望所有实现都有一个返回最终类型的 Clone() 方法
Cloner[AI[T]]
}
// 通过嵌入接口来实现 AI 接口
type AS struct {
AI[int]
a int
}
func (as AS) Clone() AS {
return AS{a: as.a}
}
// 通过嵌入接口来实现 AI 接口
type BS struct {
AI[int]
b string
}
func (bs BS) Clone() BS {
return BS{b: bs.b}
}
// 通过嵌入 AS 结构体来实现 AI 接口
type CS struct {
AS
c int
}
func (cs CS) Clone() CS {
return CS{
AS: cs.Clone(), // 错误:无法将 cs.Clone() (类型为 CS 的值) 用作结构体字面量中的 AS 类型
c: cs.c,
}
}
func main() {
var aiRef AI[int]
// 尝试获取具体对象的克隆
aiRef = &AS{a: 10}
fmt.Printf("AS: %#v\n", aiRef.Clone())
// 编译错误:
// ./main.go:42:10: 无法将 &AS{…} (类型为 *AS 的值) 作为类型 AI[int] 赋值:
// *AS 未实现 AI[int] (Clone 方法的类型错误)
// 拥有 Clone() AS
// 需要 Clone() AI[int]
aiRef = &BS{b: "hello"}
fmt.Printf("BS: %#v\n", aiRef.Clone())
// 与上述相同的编译错误
aiRef = &CS{c: 10}
fmt.Printf("CS: %#v\n", aiRef.Clone())
// 与上述相同的编译错误
}
更多关于Golang中使用泛型实现多态Clone()方法?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你好 @globalflea,
我刚刚在这里发布了一个类似问题的答案。这可能也适用于你的情况。
更多关于Golang中使用泛型实现多态Clone()方法?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好,
感谢回复,但这并未解决这一系列问题。我仍然在尝试创建“派生”类型的实例时遇到问题,或者更确切地说,我不知道如何声明一个定义,要求子结构体拥有一个返回子类型的 Clone 方法。
具体来说,我如何确保所有子类型都有一个 Clone 函数?
type AI[T any] interface {
// 希望所有实现都有一个返回最终类型的 Clone() 方法
Cloner[AI[T]]
// ?? 如何声明一个由子类型实现的泛型 Clone()?
// ?? 特别是,由于我并不知道实际的子类型是什么
}
我想在 Rust 中,我可以声明类似 Clone() -> Self 的东西。
另外,在 main() 中:
var aiRef AI[int]
aiRef = &AS{a: 10}
// ./main.go:56:10: cannot use &AS{…} (value of type *AS) as type AI[int] in assignment:
// *AS does not implement AI[int] (wrong type for Clone method)
// have Clone() AS
// want Clone() AI[int]
注意到,CloneAny() 在调用子结构体的 Clone() 函数时是有效的,对此表示感谢。
// fmt.Printf("AS: %#v\n", aiRef.Clone()) // 之前有编译错误
fmt.Printf("AS: %#v\n", CloneAny(aiRef)) // 使用 CloneAny 消除了错误
两位好。虽然没有解决方案,但想分享一个想法:
如何声明一个定义,要求子结构体拥有一个返回子类型的 Clone 方法
你是否可能过于强调强制结构体执行某些操作,而不是限制操作只接收特定类型?
换句话说,与其强制子结构体拥有 clone 方法,为什么不限制自己,要求某些操作接受 Cloner[T] 类型?
func SomethingWithClone[T Cloner[T]](c T) T {
// ...
return c.Clone()
}
强制类型实现某些功能是我在 Scala 和 Java 这类语言中的思维方式,但使用 Go 的继承机制时,我倾向于更多地关注“这个操作应该接受能够…的参数”。
也许这不可能实现?
我不知道你想做的是否可能实现,因为方法不能有类型参数,而接口是在方法中实现的。所以要求一个类型拥有 AI[int] 似乎(乍一看)是不可能的,因为方法没有类型参数。
在你分享的评论中,还有一点我认为可能是错误的(但语义上不完全确定):通过嵌入接口来实现 AI 接口,据我所知,除非你嵌入了一个已经实现该接口的结构体,否则接口不能通过嵌入来实现。在这种情况下,你直接嵌入了接口类型。
无论如何,这很有趣,我了解得还不够,我会去阅读关于泛型的内容,看看是否能在我脑海中点亮一盏灯。
补充说明:
我认为 CS 中的 Clone 方法:
func (cs CS) Clone() CS {
return CS{
AS: cs.Clone(), // 错误:无法将 cs.Clone()(CS 类型的值)用作结构体字面量中的 AS 类型
c: cs.c,
}
}
应该是:
func (cs CS) Clone() CS {
return CS{
AS: cs.AS.Clone(),
c: cs.c,
}
}
这样错误就会消失。
在Go中,使用泛型实现多态Clone()方法的关键是正确设计接口和实现关系。以下是修正后的代码:
package main
import "fmt"
type Cloner[T any] interface {
Clone() T
}
type AI[T any] interface {
Cloner[AI[T]]
}
// 基础实现
type BaseAI[T any] struct {
value T
}
func (b *BaseAI[T]) Clone() AI[T] {
return &BaseAI[T]{value: b.value}
}
// AS 实现
type AS struct {
BaseAI[int]
a int
}
func (as *AS) Clone() AI[int] {
return &AS{
BaseAI: BaseAI[int]{value: as.value},
a: as.a,
}
}
// BS 实现
type BS struct {
BaseAI[int]
b string
}
func (bs *BS) Clone() AI[int] {
return &BS{
BaseAI: BaseAI[int]{value: bs.value},
b: bs.b,
}
}
// CS 实现(嵌入AS)
type CS struct {
AS
c int
}
func (cs *CS) Clone() AI[int] {
return &CS{
AS: AS{
BaseAI: BaseAI[int]{value: cs.value},
a: cs.a,
},
c: cs.c,
}
}
func main() {
var aiRef AI[int]
aiRef = &AS{a: 10}
clonedAS := aiRef.Clone()
fmt.Printf("AS: %#v\n", clonedAS)
aiRef = &BS{b: "hello"}
clonedBS := aiRef.Clone()
fmt.Printf("BS: %#v\n", clonedBS)
aiRef = &CS{c: 10}
clonedCS := aiRef.Clone()
fmt.Printf("CS: %#v\n", clonedCS)
}
或者使用更简洁的方法,通过类型参数约束:
package main
import "fmt"
type Cloneable[T any] interface {
Clone() T
}
type AI[T any] interface {
Cloneable[AI[T]]
}
type AS struct {
a int
}
func (as *AS) Clone() AI[int] {
return &AS{a: as.a}
}
type BS struct {
b string
}
func (bs *BS) Clone() AI[int] {
return &BS{b: bs.b}
}
type CS struct {
AS
c int
}
func (cs *CS) Clone() AI[int] {
return &CS{
AS: AS{a: cs.a},
c: cs.c,
}
}
func CloneAll[T AI[E], E any](items []T) []AI[E] {
result := make([]AI[E], len(items))
for i, item := range items {
result[i] = item.Clone()
}
return result
}
func main() {
items := []AI[int]{
&AS{a: 10},
&BS{b: "hello"},
&CS{c: 20},
}
for _, item := range items {
cloned := item.Clone()
fmt.Printf("Cloned: %#v\n", cloned)
}
}
对于需要返回具体类型的情况,可以使用类型断言:
func CloneToConcrete[T any](ai AI[int]) T {
cloned := ai.Clone()
return cloned.(T)
}
func main() {
as := &AS{a: 10}
clonedAS := CloneToConcrete[*AS](as)
fmt.Printf("Concrete AS: %#v\n", clonedAS)
}
这些实现确保了类型安全,同时提供了多态的Clone()功能。

