为了账号安全,请及时绑定邮箱和手机立即绑定

如何实现具有相同方法名称和不同参数的两个接口

如何实现具有相同方法名称和不同参数的两个接口

Go
料青山看我应如是 2022-12-05 17:20:43
我有两个不同的接口(来自两个不同的包)我想实现。但是他们有冲突,就像这样:type InterfaceA interface {  Init()}type InterfaceB interface {  Init(name string)}type Implementer struct {} // Wants to implement A and Bfunc (i Implementer) Init() {}func (i Implementer) Init(name string) {} // Compiler complains它说“方法重新声明”。一个结构如何实现两个接口?
查看完整描述

3 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

正如已经回答的那样,这是不可能的,因为 Golang 不(并且可能不会)支持方法重载。

查看Golang 常见问题解答

使用其他语言的经验告诉我们,具有相同名称但不同签名的各种方法偶尔有用,但在实践中也可能令人困惑和脆弱。仅按名称匹配并要求类型一致是 Go 类型系统中的一个主要简化决策。


查看完整回答
反对 回复 2022-12-05
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

这不可能。

在 go 中,你必须有一个单一的方法签名。

您应该重命名一种方法。



查看完整回答
反对 回复 2022-12-05
?
长风秋雁

TA贡献1757条经验 获得超7个赞

方法签名必须匹配。如果你想要依赖注入,我会推荐功能选项模式。功能选项是返回在构造函数的循环中调用的其他函数的函数。这是一个如何使用功能选项和接口基础知识的示例。


package main


import (

    "fmt"

    "strconv"

)

type SomeData struct {

    data string

}

// SomeData and SomeOtherData both implement SomeInterface and SomeOtherInterface

// SomeInterface and SomeOtherInterface both implement each other.

type SomeInterface interface {

    String() string

    Set(data string)


}


func (s *SomeData)String() string {

    return s.data

}


func (s *SomeData)Set(data string)  {

    s.data = data

}


// SetDataOption is a functional option that can be used to inject a constructor dep

func SetDataOption(data string) func(*SomeData) {

   return func(s *SomeData) {

       s.Set(data)

   }

}

// NewSomeData is the constructor; it takes in 0 to many functional options and calls each one in a loop.

func NewSomeData(options ...func(s *SomeData)) SomeInterface {

   s := new(SomeData)


   for _, o := range options {

       o(s)

   }

   return s

}


//********************

type SomeOtherData struct {

    data string

    i    int

}


type SomeOtherInterface interface {

    String() string

    Set(data string)


}



func (s *SomeOtherData)String() string {

    return s.data + "  " + strconv.Itoa(s.i)

}


func (s *SomeOtherData)Set(data string)  {

    s.data = data

}



func SetOtherDataOption(data string) func(*SomeOtherData) {

   return func(s *SomeOtherData) {

      s.Set(data)

   }

}


func SetOtherIntOption(i int) func(*SomeOtherData) {

    return func(s *SomeOtherData) {

        s.i = i

    }

 }



// NewSomeOther data works just like NewSomeData only in this case, there are more options to choose from

// you can use none or any of them.

func NewSomeOtherData(options ...func(s *SomeOtherData)) SomeOtherInterface {

   s := new(SomeOtherData)


   for _, o := range options {

       o(s)

   }

   return s

}


//*********************************

// HandleData accepts an interface

// Regardless of which underlying struct is in the interface, this function will handle 

// either by calling the methods on the underlying struct.

func HandleData(si SomeInterface) {

    fmt.Println(si)  // fmt.Println calls the String() method of your struct if it has one using the Stringer interface

}


func main() {

    someData := NewSomeData(SetDataOption("Optional constructor dep"))

    someOtherData := NewSomeOtherData(SetOtherDataOption("Other optional constructor dep"), SetOtherIntOption(42))

    HandleData(someData) // calls SomeData.String()

    HandleData(someOtherData) // calls SomeOtherData.String()

    someOtherData = someData // assign the first interface to the second, this works because they both implement each other.

    HandleData(someOtherData) // calls SomeData.String()  because there is a SomeData in the someOtherData variable.

    

}


查看完整回答
反对 回复 2022-12-05
  • 3 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信