Golang中如何使用接口实现包之间的最佳交互方式
Golang中如何使用接口实现包之间的最佳交互方式 我正在寻找如何绑定两个包的解决方案。 我做了一个示例(可惜它无法运行)
Go Playground - The Go Programming Language
这会产生一个错误:
# play.ground
./prog.go:11:15: cannot use dlg (type dialog.Dialog) as type config.dialog in argument to cfg.SetDialog:
dialog.Dialog does not implement config.dialog (wrong type for SetGlobalConfig method)
have SetGlobalConfig(dialog.Config)
want SetGlobalConfig(config.Config)
我学习的主要相关链接:
The Go Programming Language Specification - The Go Programming Language
和
据我理解,原因是:
已定义的类型 总是与其他任何类型都不同。
我查看了这里的示例 CodeReviewComments · golang/go Wiki · GitHub,没发现和我做的有什么不同。我尝试通过移除 SetGlobalConfig 函数中的参数来简化逻辑,然后它就能工作了。
Go Playground - The Go Programming Language
但在这种情况下,我无法将配置实例发送到对话框,反之亦然。
所以问题是——是否存在一种解决方案可以在包之间传递对象?
更多关于Golang中如何使用接口实现包之间的最佳交互方式的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我现在在手机上,无法立即深入查看,但我认为你需要使用接口类型作为你的 Config 类型;它不能是结构体。
我几小时前回答了一个相关问题此处。请查看关于接口类型以及我在示例中使用的 myReader 类型部分。
你好,Sean,感谢你在相关帖子中给出的详尽解释!我注意到,核心类型大多操作的是标准类型,例如 bool、int、string 等。那么如果我们想使用一些自定义的外部类型呢?我们确实希望在同一个包中进行复制/实现。我想接口在这里会有所帮助。这实际上正是我试图在我的代码中实现的。
我认为你必须使用接口类型作为你的
Config类型;它不能是结构体。
能否请你简要举例说明一下你会如何实现这一点?
非常感谢你提供的示例,这非常有价值!
你的示例在接口中使用了简单的类型。我尝试处理一个包含来自不同包的属性类型的类型,并尝试使用接口来实现。看起来,这似乎是错误的。
Go 只有一种从根路径到包的访问方式。我的想法是使用根包作为两个包之间的通信中介,但每个包理论上只知道另一个包的存在,因此逻辑保留在相关的包中。如果这是错误的,那就意味着只有根包可以操作子包,而包之间甚至不能使用接口进行交互。
在 Go 中,是否有构建正确应用程序架构的最佳实践?这不是我第一次尝试构建一个 Go 小项目来加深理解,而每次对接口的理解都阻碍了我。我来自 PHP 世界,我理解经典 OOP 和 Go 中接口的区别,但我找不到应用程序架构设计的严格方法。你有什么建议吗?
在Go中,接口是实现包之间解耦交互的最佳方式。你的问题源于类型定义不同,即使底层结构相同,dialog.Config和config.Config也被视为不同的类型。
解决方案:使用共享接口
1. 创建共享接口包(推荐)
创建一个独立的包来定义接口:
// shared/interfaces.go
package shared
type Config interface {
GetValue() string
SetValue(string)
}
type Dialog interface {
SetGlobalConfig(Config)
Show()
}
2. 在各包中实现接口
// config/config.go
package config
import "shared"
type MyConfig struct {
value string
}
func (c *MyConfig) GetValue() string {
return c.value
}
func (c *MyConfig) SetValue(v string) {
c.value = v
}
func NewConfig() shared.Config {
return &MyConfig{}
}
// dialog/dialog.go
package dialog
import "shared"
type MyDialog struct {
config shared.Config
}
func (d *MyDialog) SetGlobalConfig(cfg shared.Config) {
d.config = cfg
}
func (d *MyDialog) Show() {
// 使用配置
if d.config != nil {
println("Config value:", d.config.GetValue())
}
}
func NewDialog() shared.Dialog {
return &MyDialog{}
}
3. 主程序中使用
package main
import (
"config"
"dialog"
"shared"
)
func main() {
// 创建配置
cfg := config.NewConfig()
cfg.SetValue("Hello from config")
// 创建对话框
dlg := dialog.NewDialog()
// 设置配置 - 现在可以正常工作
dlg.SetGlobalConfig(cfg)
// 显示对话框
dlg.Show()
}
替代方案:使用嵌入和类型断言
如果不想创建单独的接口包:
// config/config.go
package config
type Config interface {
GetValue() string
SetValue(string)
}
type MyConfig struct {
value string
}
func (c *MyConfig) GetValue() string {
return c.value
}
func (c *MyConfig) SetValue(v string) {
c.value = v
}
// dialog/dialog.go
package dialog
import "config"
type Dialog interface {
SetGlobalConfig(config.Config)
Show()
}
type MyDialog struct {
config config.Config
}
func (d *MyDialog) SetGlobalConfig(cfg config.Config) {
d.config = cfg
}
关键点
- 接口定义位置:接口应该定义在使用它的地方,而不是实现它的地方
- 避免循环依赖:通过接口解耦包之间的依赖
- 最小接口原则:只暴露必要的方法
你的错误是因为dialog.Config和config.Config虽然结构相同,但Go编译器将它们视为完全不同的类型。通过共享接口,可以解决这个问题。


