Struct does not implement interface if it has a function which parameter implement interface

后端 未结 2 1722
余生分开走
余生分开走 2021-01-28 21:57

I have a package in which I have two interfaces

package main
type A interface {
    Close()
}
type B interface {
    Connect() (A, error)
}

I h

相关标签:
2条回答
  • 2021-01-28 22:37

    The returned type for your Connect method should be A and not *C.

    The way you defined the Connect method is that it should return an interface, not a specific type. You will still be able to return *C as it implements the A interface.

    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)
        println("successfully created new C:", c)
        return c, nil
    }
    
    func test(b B) {
        b.Connect()
    }
    
    func main() {
        d := new(D)
        test(d)
    }
    

    Outputs

    successfully created new C: 0xe28f0

    Try it out yourself here

    0 讨论(0)
  • 2021-01-28 22:51

    For implementing the interface there is one to concern about which is:

    A Go type satisfies an interface by implementing the methods of that interface, nothing more. This property allows interfaces to be defined and used without having to modify existing code. It enables a kind of structural typing that promotes separation of concerns and improves code re-use, and makes it easier to build on patterns that emerge as the code develops.

    The error you are getting because the struct D you are using as an argument to test function does not implement the interface. The reason behind this is that the function Connect you are using with receiver D is different. Since it has different return type:

    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
    }
    

    while if you want to implement the interface B the function definition along with its return type should match the function in interface B which is

    type B interface {
        Connect() (A, error)
    }
    

    So if you want to implement the interface the Connect method you are using should match the Connect method of the interface B

    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)
    }
    

    Check on Go Playground

    Consider this simple interface to represent an object that can compare itself with another value:

    type Equaler interface {
        Equal(Equaler) bool
    }
    

    and this type, T:

    type T int
    func (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler
    

    The argument type of T.Equal is T, not literally the required type Equaler.

    In Go, the type system does not promote the argument of Equal; that is the programmer's responsibility, as illustrated by the type T2, which does implement Equaler:

    type T2 int
    func (t T2) Equal(u Equaler) bool { return t == u.(T2) }  // satisfies Equaler
    
    0 讨论(0)
提交回复
热议问题