Golang中如何将对象添加到[]interface{}并调用其Display()方法
Golang中如何将对象添加到[]interface{}并调用其Display()方法 我已完成以下操作:
- 定义了一个包含 Display() 方法的"父"接口
- 创建了 2 个子结构体,分别实现了各自的 Display() 方法
- 在 main() 中创建了 2 个子对象并将它们添加到:
availableObjs[]interface{} - 现在,在 For 循环中,想要获取对象并调用其相应的 Display() 函数。这就是我卡住的地方
GoPlayground 代码: https://play.golang.org/p/jdHpueokrEk
相同代码内联:
package main
import (
"fmt"
"reflect"
)
////// 包含 Display() 方法的父接口
type Parent interface {
Display()
}
// 2 个子结构体实现各自的 Display() 方法
type Child1 struct {
name1 string
}
type Child2 struct {
name2 string
}
func (c1 Child1) Display() {
fmt.Println("c1Name : ", c1.name1)
}
func (c2 Child2) Display() {
fmt.Println("c2Name : ", c2.name2)
}
////////////////////////////////////////////
// 维护已创建的对象
var availableObjs []interface{}
func main() {
//// 创建 2 个对象
c1 := Child1{"Child1"}
c2 := Child2{"Child2"}
// 将 2 个对象添加到 availableObjs
availableObjs = append(availableObjs, c1)
availableObjs = append(availableObjs, c2)
// 现在,想要从接口中获取对象并调用其相应的 Display() 方法
for _, obj := range availableObjs {
fmt.Println("")
fmt.Println("Obj Got = ",obj)
fmt.Println("Obj type = ",reflect.TypeOf(obj))
//obj.Display() // <-- 问题行
}
}
更多关于Golang中如何将对象添加到[]interface{}并调用其Display()方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
两种方法对我都有效。我会选择方案2。感谢您的帮助!
更多关于Golang中如何将对象添加到[]interface{}并调用其Display()方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
为什么你要使用 interface{} 切片而不是 Parent 类型的切片?你当然可以通过类型断言来调用 Display 方法,如下所示:
for _, obj := range availableObjs {
p := obj.(Parent)
p.Display()
}
但更直接的方式是直接使用 Parent 类型的切片:
r availableObjs []Parent
func main() {
//// Creating 2 objects
c1 := Child1{"Child1"}
c2 := Child2{"Child2"}
// Adding 2 objects to availableObjs
availableObjs = append(availableObjs, c1)
availableObjs = append(availableObjs, c2)
// Now, want to fetch the Object from Interface and call its respective Display() fn.
for _, obj := range availableObjs {
obj.Display()
}
}
要解决这个问题,你需要将 interface{} 类型断言为 Parent 接口类型,然后调用 Display() 方法。以下是修改后的代码:
package main
import (
"fmt"
)
type Parent interface {
Display()
}
type Child1 struct {
name1 string
}
type Child2 struct {
name2 string
}
func (c1 Child1) Display() {
fmt.Println("c1Name : ", c1.name1)
}
func (c2 Child2) Display() {
fmt.Println("c2Name : ", c2.name2)
}
var availableObjs []interface{}
func main() {
c1 := Child1{"Child1"}
c2 := Child2{"Child2"}
availableObjs = append(availableObjs, c1)
availableObjs = append(availableObjs, c2)
for _, obj := range availableObjs {
fmt.Println("")
fmt.Println("Obj Got = ", obj)
// 类型断言为 Parent 接口
if parent, ok := obj.(Parent); ok {
parent.Display()
} else {
fmt.Println("对象未实现 Parent 接口")
}
}
}
运行结果:
Obj Got = {Child1}
c1Name : Child1
Obj Got = {Child2}
c2Name : Child2
关键修改是在循环中使用类型断言 obj.(Parent),这会检查 interface{} 是否实现了 Parent 接口。如果断言成功,就可以调用 Display() 方法。
另一种更简洁的写法是直接使用 Parent 类型的切片:
var availableObjs []Parent
func main() {
c1 := Child1{"Child1"}
c2 := Child2{"Child2"}
availableObjs = append(availableObjs, c1)
availableObjs = append(availableObjs, c2)
for _, obj := range availableObjs {
fmt.Println("")
fmt.Println("Obj Got = ", obj)
obj.Display() // 直接调用,无需类型断言
}
}
这样就不需要在循环中进行类型断言,代码更加简洁。

