go - 如果结构有参数实现接口的方法,则结构不实现接口
问题描述
我有一个包,其中有两个接口
package main
type A interface {
Close()
}
type B interface {
Connect() (A, error)
}
我还有两个实现这些接口的结构
type C struct {
}
func (c *C) Close() {
}
type D struct {
}
func (d *D) Connect() (*C, error) {
c := new(C)
return c, nil
}
接下来我有一个函数作为参数需要一个实现接口 B 的对象
func test(b B) {
}
最后,在 main() 函数中,我创建了 D 结构对象并想调用 test() 函数
func main() {
d := new(D)
test(d)
}
如果我尝试构建该软件包,则会出现错误。
不能在测试的参数中使用 d (type *D) 作为 type B: *D does not implement B (error type for Connect method) have Connect() (*C, error) want Connect() (A, error)
这是我使用外部包并希望模拟测试结构的代码的简单示例。使用接口而不是类型有什么解决方案吗?
解决方案
为了实现接口,需要关注的是:
Go 类型通过实现接口的方法来满足接口,仅此而已。此属性允许定义和使用接口,而无需修改现有代码。它支持一种促进关注点分离和改进代码重用的结构类型,并且更容易在代码开发时出现的模式上进行构建。
您收到的错误是因为D
您用作测试函数参数的结构没有实现接口。这背后的原因是Connect
您与接收器一起使用的功能D
不同。因为它有不同的返回类型:
func (d *D) Connect() (*C, error) { // the struct D does not implement the interface B because of wrong function definition to interface B function
c := new(C)
return c, nil
}
而如果要实现接口B
,则函数定义及其返回类型应与接口中的函数相匹配B
,即
type B interface {
Connect() (A, error)
}
所以如果你想实现接口,你使用的 Connect 方法应该匹配接口 B 的 Connect 方法
package main
type A interface {
Close()
}
type B interface {
Connect() (A, error)
}
type C struct {
}
func (c *C) Close() {
}
type D struct {
}
func (d *D) Connect() (A, error) {
c := new(C)
return c, nil
}
func test(b B) {}
func main() {
d := new(D)
test(d)
}
检查去游乐场
考虑这个简单的接口来表示一个可以将自己与另一个值进行比较的对象:
type Equaler interface {
Equal(Equaler) bool
}
这种类型,T:
type T int
func (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler
T.Equal 的参数类型是 T,而不是字面上要求的 Equaler 类型。
在 Go 中,类型系统不提倡 Equal 的参数;这是程序员的责任,如 T2 类型所示,它确实实现了 Equaler:
type T2 int
func (t T2) Equal(u Equaler) bool { return t == u.(T2) } // satisfies Equaler
推荐阅读
- search - 浏览 Uipath 中的目录
- c - PBC 库实现
- javascript - 用不同位置的多个字符替换单个字符
- python - 仅执行某项任务 x 次
- kotlin - 从 JWT Claims 获取角色的更好的 Kotlin 方式
- batch-file - 更改 Windows 启动命令的标题
- c# - 对象的反序列化给出错误:无法反序列化当前的 JSON 对象?
- c# - 用 C# 覆盖 FTP 服务器上已存在的文件时出现“(550)文件不可用”
- ios - 上传到itunesconnect并打开位码后找不到iOS应用程序主要目标符号文件
- html - 在 angular7 中,如何在显示项目列表时更改 mat-select 的高度?