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

10 回复
for _, i := range n1 {
   fmt.Println(i.GetName())
}

更多关于Golang中如何将其他包返回的结构体列表用于main.go的接口?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你不能为一个模块实现接口,只能为一个类型实现接口。

感谢Norbert。我正在尝试为模块实现接口,但目前还没有成功。

希望很快我能找到方法。

main 包不能被导入到其他包中,因此你无法引用或使用其中定义的任何类型或函数。

所以你需要将这些类型移到一个包中,然后将其导入到 main 包和你的其他包中。

main.Infomodules.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是最合适的。

回到顶部