当前位置:网站首页>[go] go language interface

[go] go language interface

2022-06-22 23:46:00 weixin_ forty-three million two hundred and twenty-four thousan

Go The interface implementation mechanism is very simple , As long as the target type method set contains all the methods declared by the interface , Is considered to implement the interface , No need to make a display statement . Of course , Target types can implement multiple interfaces . The benefits of this are : We can implement the type first , And then abstract out the required interfaces .

At the same time Go There is no concept of inheritance in language , So structure 、 There is no parent-child relationship between interfaces ,Go Language advocates combination , Use composition to achieve the purpose of code reuse , This is also more flexible .

From the perspective of internal implementation , The interface itself is also a structure type , But the compiler makes a lot of restrictions on it :

  • Cannot have field
  • You can't define your own method
  • Only methods can be declared , Can't achieve
  • Other interface types can be embedded

The interface usually uses er As the name suffix .

Empty interface

If the interface interface{} No method is declared , Then it is an empty interface , Its purpose is similar to the root type in object-oriented Object, Can be assigned to any type of object .

var i interface{} = 1
fmt.Println(i)

Go Medium interface{} It is often used for parameter passing , To help achieve generic effects in other languages : Like the following Foo Function is a function related to business processing , Need one bucketId, The upper layer may pass in string form "1234", It could also be a numerical form 1234

func Foo(arg interface{}) (err error) {
    bucketId, err := parseBucketIdParam(arg)
    if err != nil {
        return err
    }

    //  The following is the normal business processing 
    fmt.Println("bucketId: ", bucketId)
    return
}

func parseBucketIdParam(arg interface{}) (bucketId int64, err error) {
    if bucketIdStr, ok := arg.(string); ok {
        bucketId, err = strconv.ParseInt(bucketIdStr, 10, 64)
        if err != nil {
            return
        }
    } else if bucketIdInt, ok := arg.(int); ok {
        bucketId = int64(bucketIdInt)
    } else if bucketIdInt64, ok := arg.(int64); ok {
        bucketId = bucketIdInt64
    } else {
        err = fmt.Errorf("not support bucketId param")
    }

    return
}

If there are too many types to convert ,if else Verbose statement , Then you can use type-switch, More flexible

func foo(v interface{}) {
    switch v.(type) {
    case nil:
        fmt.Println("type is nil")
    case int:
        fmt.Println("type is int")
    case string:
        fmt.Println("type is string")
        default:
                fmt.Println("unknown type")
    }
}

foo(123)
foo("123")

But here's the thing type-switch I won't support it fallthrought

Anonymous interface

Other anonymous interfaces can be embedded in the interface , Then the target type method set must have all methods including embedded interface methods to realize the interface . meanwhile , Cannot embed itself or loop , That will lead to recursive embedding .

type stringer interface {
    string() string
}

type tester interface {
    stringer
    test()
}

type data struct{}

func (*data) test() {  
    //...
}
//  Must be realized  stringer  Interface 
func (data) string() string {  
    // ...
}

Interface and polymorphism

type Eater interface{
    Eat()
}

type Cat struct {
}
func (cat Cat) Eat() {
    fmt.Println("eat fish")
}

type Dog struct {
}
func (dog Dog) Eat() {
    fmt.Println("eat bone")
}

func Foo(i Eater) {
    i.Eat()
}

func main() {
    cat := Cat{}
    Foo(cat)

    dog := Dog{}
    Foo(dog)
}

Output :

image.png

Can I compare interfaces ?

interface It can be compared in some scenarios .

  • Without method interface:
    type Fooer interface {
    }
    
    type Barer interface {
    }
    
    func main() {
        var foo Fooer
        var bar Barer
        fmt.Println(foo == bar) //  Output true
    
        fooInstance := 1
        barInstance := 1
        fmt.Println(fooInstance == barInstance) //  Output is true
    
        fooInstance2 := 1
        barInstance2 := 10
        fmt.Println(fooInstance2 == barInstance2) //  Output is false
    }
    
  • With methods interface, And the method name is the same :
    type Fooer interface {
        value() int
    }
    
    type Barer interface {
        value() int
    }
    
    type Foo int
    
    func (foo Foo) value() int {
        return 1
    }
    
    type Bar int
    
    func (bar Bar) value() int {
        return 1
    }
    
    func main() {
        var foo Fooer
        var bar Barer
        fmt.Println(foo == bar) //  Output true
    
        fooInstance := Foo(10)
        barInstance := Bar(10)
        fmt.Println(fooInstance == barInstance) // invalid operation: fooInstance == barInstance (mismatched types Foo and Bar)
    }
    
  • With methods interface, And the method names are different :
    type Fooer interface {
        FooerValue() int
    }
    
    type Barer interface {
        BarerValue() int
    }
    
    type Foo int
    
    func (foo Foo) FooerValue() int {
        return 1
    }
    
    type Bar int
    
    func (bar Bar) BarerValue() int {
        return 1
    }
    
    func main() {
        var foo Fooer
        var bar Barer
        fmt.Println(foo == bar) // invalid operation: foo == bar (mismatched types Fooer and Barer)
    
        fooInstance := Foo(10)
        barInstance := Bar(10)
        fmt.Println(fooInstance == barInstance) // invalid operation: fooInstance == barInstance (mismatched types Foo and Bar)
    }
    
  • interface and nil Compare
    type Fooer interface {
        FooerValue() int
    }
    
    type Foo int
    
    func (foo Foo) FooerValue() int {
            return 1
    }
    
    func main() {
        var foo Fooer
        fmt.Println(nil == foo) // true
    
        fooInstance := Foo(10)
        fmt.Println(nil == fooInstance) // invalid operation: fooInstance == barInstance (mismatched types Foo and Bar)
    }
原网站

版权声明
本文为[weixin_ forty-three million two hundred and twenty-four thousan]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/173/202206222124162485.html