具有接收指定接口参数的函数的Golang接口

具有接收指定接口参数的函数的Golang接口,go,interface,Go,Interface,我尝试在Go中使用接口,以实现两个优势: 保护我自己不要混淆变量顺序 使软件包相互独立,以便有一天我可以轻松地替换其中一个 在我的特殊情况下,我可以找到解决办法,但我不明白为什么我尝试的方式不起作用,它看起来简单而合乎逻辑 这就是我要做的 在一个包(命名的处理程序)中,我有一个描述我需要的函数的接口,只是一些接收帐户的东西 包处理程序 类型Accounter接口{ 账户 } 类型帐户接口{ AccountID()int64 UserID()int64 OtherID()int64 } 在我的程

我尝试在Go中使用接口,以实现两个优势:

  • 保护我自己不要混淆变量顺序
  • 使软件包相互独立,以便有一天我可以轻松地替换其中一个
  • 在我的特殊情况下,我可以找到解决办法,但我不明白为什么我尝试的方式不起作用,它看起来简单而合乎逻辑

    这就是我要做的

    在一个包(命名的处理程序)中,我有一个描述我需要的函数的接口,只是一些接收
    帐户的东西

    包处理程序
    类型Accounter接口{
    账户
    }
    类型帐户接口{
    AccountID()int64
    UserID()int64
    OtherID()int64
    }
    
    在我的程序的另一个包(名为accounter)中,我有与接口匹配的函数,以及
    Account
    接口的定义,以避免从第一个包导入此接口

    包会计
    类型帐户接口{
    AccountID()int64
    UserID()int64
    OtherID()int64
    }
    func(x*账户)ADDCOUNT(a账户){
    ...
    }
    
    但是
    go vet
    告诉我我不能做这样的事情:

    configure_stats_loader.go:109:64: cannot use x (type *accounter.Accounter) as type handlers.Accounter in argument to handlers.AddAccHandler:
        *accounter.Accounter does not implement handlers.Accounter (wrong type for AddAccount method)
            have AddAccount(accounter.Account)
            want AddAccount(handlers.Account)
    
    在这种情况下,我必须解决以下问题:

  • 从其中一个包导入
    帐户
    接口
  • 在标准go类型中定义函数接收值,如
    (UserID、accountid、OtherID int64)
  • 在第一种情况下,我在包中失去了独立性,在将来的某个时候,如果不重写一些代码(不是很多代码,但仍然如此),我将无法替换
    Accounter
    接口;在第二种情况下,如果我在
    Account
    中有很多类似的方法和很多参数,我可能会意外地混淆变量的顺序。例如,意外地将
    AccountID
    用作
    UserID

    现在的问题是:有什么办法可以让所有的优势都发挥出来吗?避免混淆变量顺序,避免从一个包导入另一个包。

    响应@Marc注释,“第三方”包非常适合定义常见类型。这是一种常见的做法,尤其是在处理问题时

    此外,根据《保持接口简短》:

    只有一个或两个方法的接口在Go代码中很常见

    因此,请避免费劲的getter/setter定义,并将重点放在更大的操作上。因此,我建议您在“类型”套餐中:


    这是独立包中的两个独立接口,它们不相同。在单个包中定义接口并从其他包中重用它。如果要将这两个包分开,请使用第三个只包含接口的包。@Marc谢谢。嗯,第三个方案似乎有点麻烦,但它是一个解决方案。不要解决问题,你可能只有“一天”。除非您正在设计一个API,否则您总是可以在以后移动/替换包。
    package mydefs
    
    // concrete type: used for Creation and lookup
    type Account struct {
        ID      int64
        UserID  int64
        OtherID int64
    }
    
    // abstract interface: keep method list short
    type Accounter interface {
        Add(a Account) error             //
        Get(a Account) (Account, error)  // use concrete type as a lookup request type
    }