菜鸟请教 interface 的使用

zong400 · 2024-12-6 15:56:07 · 316 次点击

有 2 个 struct A B,分别有自己的 New 方法 NewA(),NewB(),并且已经实现了 interface C { Scan ()} 想通过命令行传参,在 main 方法使用的时候选择实例化 A or B 并且执行 scan()

run.go A

目前的写法是用 switch 判断,感觉不太对头,有优雅的写法吗?

switch svc {
case "A":
  a := NewA()
  go func(c C) {
    c.Scan()
  }(a)
case "B":
  b := NewB()
  go func(c C) {
    c.Scan()
  }(b)
}
举报· 316 次点击
登录 注册 站外分享
2 条回复  
ncbdwss 初学 2024-12-6 16:21:43
package main import ( "fmt" ) type C interface { Scan() } type A struct{} func NewA() *A { return &A{} } func (a *A) Scan() { fmt.Println("A Scan") } type B struct{} func NewB() *B { return &B{} } func (b *B) Scan() { fmt.Println("B Scan") } // 工厂函数,返回不同的类型 func NewInstance(svc string) (C, error) { switch svc { case "A": return NewA(), nil case "B": return NewB(), nil default: return nil, fmt.Errorf("invalid service: %s", svc) } } func main() { svc := "A" // 可以通过命令行参数获取 svc // 通过工厂函数选择实例化对象 c, err := NewInstance(svc) if err != nil { fmt.Println("Error:", err) return } // 启动并执行 Scan() go func(c C) { c.Scan() }(c) // 阻塞,避免主程序提前退出 select {} } 说明: NewInstance(svc string):通过传入的 svc 字符串来决定实例化 A 或 B ,返回 C 类型接口。 在 main 函数中,通过 NewInstance 获取具体的实例并执行 Scan() 方法。 使用 go 协程来异步执行 Scan() 方法。 通过 select{} 保证主程序不会提前退出。 这样做的好处: 通过工厂模式将实例化逻辑集中管理,避免了 switch 语句的重复使用。 如果以后需要添加更多的服务,只需在 NewInstance 函数中增加对应的 case ,而不需要修改 main 函数的核心逻辑,增加了可扩展性。 这种写法比直接使用 switch 更加优雅、清晰,并且具有更好的可扩展性。
zong400 楼主 小成 2024-12-6 16:32:25
@ncbdwss 虽然是 gpt 的,也感谢你 我发现根本错的地方是我的 New 方法返回了 A ,所以 main 里面实例化的 a,b 类型错了 应该返回 C 才对 func NewA() C
返回顶部