Golang中如何实现返回接口类型的接口方法

Golang中如何实现返回接口类型的接口方法 https://play.golang.org/p/BCfG7-6IctI

package main

import "fmt"

type Barer interface {
	Bar() string
}

type Fooer interface {
	Foo() Barer
}

type bar struct {
}

func (bar) Bar() string {
	return "bar"
}

type foo struct {
}

func (foo) Foo() bar {
	return bar{}
}

func print(foo Fooer) {
	fmt.Println(foo.Foo().Bar())
}

func main() {
	x := foo{}
	print(x)
}

为什么这段代码编译失败

./prog.go:33:7: cannot use x (type foo) as type Fooer in argument to print:
	foo does not implement Fooer (wrong type for Foo method)
		have Foo() bar
		want Foo() Barer

func (foo) Foo() bar 确实返回了 Barer,但是 bar 没有被检测为 Barer


更多关于Golang中如何实现返回接口类型的接口方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

是的,我明白这样是可行的。但我只是想知道,为什么我们不能返回具体的结构体而不是接口。

更多关于Golang中如何实现返回接口类型的接口方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


因为在接口定义中,你声明需要返回 Barer 的方法,而不是返回 bar。方法签名必须完全匹配。

引用 jauhararifin:

func (foo) Foo() bar {
	return bar{}
}

这应该可以工作(无法测试):

func (foo) Foo() Barer {
	return bar{}
}

在 Go 语言中,接口实现需要严格匹配方法签名。你的代码中 Foo() 方法返回的具体类型 bar 虽然实现了 Barer 接口,但方法签名返回的是具体类型而不是接口类型。

问题在于:

  • Fooer 接口要求 Foo() Barer
  • 你的 foo 类型实现了 Foo() bar
  • 虽然 bar 实现了 Barer,但方法签名不匹配

修正方法是将 Foo() 方法的返回类型改为 Barer

package main

import "fmt"

type Barer interface {
	Bar() string
}

type Fooer interface {
	Foo() Barer
}

type bar struct{}

func (bar) Bar() string {
	return "bar"
}

type foo struct{}

// 关键修改:返回 Barer 接口类型而不是具体类型 bar
func (foo) Foo() Barer {
	return bar{}
}

func print(foo Fooer) {
	fmt.Println(foo.Foo().Bar())
}

func main() {
	x := foo{}
	print(x)
}

或者,如果你需要保持返回具体类型,可以使用接口嵌入:

type foo struct{}

func (f foo) Foo() bar {
	return bar{}
}

// 添加一个适配器方法
func (f foo) AsFooer() Fooer {
	return fooAdapter{f}
}

type fooAdapter struct {
	foo
}

func (fa fooAdapter) Foo() Barer {
	return fa.foo.Foo()
}

func main() {
	x := foo{}
	print(x.AsFooer())
}

第一种方法是最直接和推荐的解决方案。Go 的接口实现要求方法签名完全匹配,包括参数和返回值的类型。

回到顶部