Golang中如何将其他包返回的结构体列表用于main.go的接口?
Golang中如何将其他包返回的结构体列表用于main.go的接口? 大家好,
!新手警告! 我一直在努力解决这个问题,但不确定在 Go 中这样做是否正确。
main.go:
package main
import (
"fmt"
"modules"
)
type Infoer interface {
GetName() string
}
func main() {
var n1 Infoer
n1 = modules.GetInfo()
fmt.Println(n1)
}
helper.go @ modules/helper.go … 在 main.go 中被导入:
package modules
type Info struct {
Name string
}
func (i Info) GetName() string {
return i.Name
}
func GetInfo() []Info {
return []Info{
{Name: "John"},
{Name: "Jane"},
}
}
错误:
无法将 n1(类型 []modules.Info)用作赋值中的类型 Infoer: []modules.Info 未实现 Infoer(缺少 GetName 方法)
我理解错误的原因,但无法想出解决方案。
任何帮助都将不胜感激。
谢谢!
更多关于Golang中如何将其他包返回的结构体列表用于main.go的接口?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
for _, i := range n1 {
fmt.Println(i.GetName())
}
更多关于Golang中如何将其他包返回的结构体列表用于main.go的接口?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你不能为一个模块实现接口,只能为一个类型实现接口。
感谢Norbert。我正在尝试为模块实现接口,但目前还没有成功。
希望很快我能找到方法。
main 包不能被导入到其他包中,因此你无法引用或使用其中定义的任何类型或函数。
所以你需要将这些类型移到一个包中,然后将其导入到 main 包和你的其他包中。
main.Info 和 modules.Info 是不同的类型,你不能将它们互换使用。
正确的方法是实现接口 I. modules,并在 main 中合适的地方使用 modules.Info。
Charles,
非常感谢您的回复。
我主要想了解在 main.go 中是否有可能在 n1 上使用接口?还是我的想法太疯狂了?
在 Python 的世界里,我可以从模块中获取任何类型的数据,并将其发送给函数,只要该函数的参数接受它。
这两种类型是不同的,并且它们也不共享一个公共接口。
main.Infoer 要求类型实现一个方法 GetName(),该方法返回类型为 []main.Info 的内容,而 modules.Info.GetName() 返回的是 []modules.Info。
所以让我再说一遍,你需要从 main 中提取类型和接口,并将它们移动到另一个包中,比如 modules 或其他地方。
感谢Norbert。
我正在尝试从“modules”包中导入。以下是main.go和modules/helper.go文件的内容:
路径 main.go:
package main
import (
"fmt"
"interface_hello_1/modules"
)
type Infoer interface {
GetName() []Info
}
type Info struct {
Name string
Age int
}
func (i Info) GetName() []Info {
Infos := []Info{
{Name: "Foo", Age: 3},
}
return Infos
}
func infoPrint(i Infoer) {
fmt.Println(i.GetName())
}
func main() {
in := Info{}
var i Infoer = in
fmt.Println(i.GetName()) // 可以工作
// 从 modules 包中
n1 := modules.Info{}.GetName()
// 这里需要指导... 以使用接口
var i1 Infoer = n1
i1.GetName()
}
路径 modules/helper.go:
package modules
type Info struct {
Name string
Age int
}
func (t Info) GetName() []Info {
Infos := []Info{
{Name: "Bar", Age: 4},
}
return Infos
}
尝试了类似下面的操作;它是有效的。我不太确定这是否是正确的做法,或者是否有一种更优雅的方式在 Go 中实现。
路径 main.go:
package main
import (
"fmt"
"interface_hello_1/modules"
)
// Infoer 接口
type Infoer interface {
GetName() []Info
}
// Info 结构体用于保存 Name 和 Age;实现了 Infoer 接口
type Info struct {
Name string
Age int
}
// GetName 方法
func (i Info) GetName() []Info {
Infos := []Info{
{Name: i.Name, Age: i.Age},
}
return Infos
}
func infoPrint(i Infoer) {
fmt.Println(i.GetName())
}
func main() {
in := Info{Name: "Foo", Age: 3}
var i Infoer = in
fmt.Println(i.GetName()) // 有效
// 来自 modules 模块
n1 := modules.Info{}.GetName()
var in1 Info
for _, item := range n1 {
in1.Name = item.Name
in1.Age = item.Age
}
var i1 Infoer = in1
fmt.Println(i1.GetName())
}
路径 modules/helper.go:
package modules
type Info struct {
Name string
Age int
}
func (t Info) GetName() []Info {
Infos := []Info{
{Name: "Bar", Age: 4},
}
return Infos
}
输出:
$ go run main.go
[{Foo 3}]
[{Bar 4}]
问题在于你试图将 []Info 切片赋值给单个 Infoer 接口变量。GetInfo() 返回的是切片,而不是单个值。
以下是几种解决方案:
方案1:处理切片中的单个元素
package main
import (
"fmt"
"modules"
)
type Infoer interface {
GetName() string
}
func main() {
// 获取整个切片
infos := modules.GetInfo()
// 处理第一个元素
var n1 Infoer
if len(infos) > 0 {
n1 = infos[0]
fmt.Println(n1.GetName()) // 输出: John
}
// 或者遍历所有元素
for _, info := range infos {
var n Infoer = info
fmt.Println(n.GetName())
}
}
方案2:修改 GetInfo() 返回单个值
// modules/helper.go
package modules
type Info struct {
Name string
}
func (i Info) GetName() string {
return i.Name
}
// 返回单个值
func GetInfo() Info {
return Info{Name: "John"}
}
方案3:创建切片接口
package main
import (
"fmt"
"modules"
)
type Infoer interface {
GetName() string
}
func main() {
infos := modules.GetInfo()
// 创建接口切片
var infoers []Infoer
for _, info := range infos {
infoers = append(infoers, info)
}
// 使用接口切片
for _, infoer := range infoers {
fmt.Println(infoer.GetName())
}
}
方案4:使用类型断言(如果只需要部分功能)
package main
import (
"fmt"
"modules"
)
func main() {
infos := modules.GetInfo()
// 直接使用具体类型
for _, info := range infos {
fmt.Println(info.GetName())
fmt.Println(info.Name) // 也可以直接访问字段
}
}
最常见的是方案1或方案3,具体取决于你的需求。如果需要将整个切片作为接口使用,方案3是最合适的。

