This is the 14th day of my participation in the August More Text Challenge. For details, see:August is more challenging

Continue learning about interfaces from the previous article.

The embedded interface

package main

import "fmt"

type Human interface {
    Len()
}
type Student interface {
    Human
}

type Test struct{}func (h *Test) Len(a) {
    fmt.Println("Success")}func main(a) {
    var s Student
    s = new(Test)
    s.Len()
}
Copy the code

Running result:

successfulCopy the code

Example code:

package test

import (
    "fmt"
)

type Controller struct {
    M int32
}

type Something interface {
    Get()
    Post()
}

func (c *Controller) Get(a) {
    fmt.Print("GET")}func (c *Controller) Post(a) {
    fmt.Print("POST")}package main

import (
    "fmt"
    "test"
)

type T struct {
    test.Controller
}

func (t *T) Get(a) {
    //new(test.Controller).Get()
    fmt.Print("T")}func (t *T) Post(a) {
    fmt.Print("T")}func main(a) {
    var something test.Something
    something = new(T)
    var t T
    t.M = 1
    // t.Controller.M = 1
    something.Get()
}
Copy the code

Running result:

T
Copy the code

Controller implements all the methods on Something’s interface. When the Controller structure is called from the structure T, T inherits from The Controller structure in Java. Therefore, instead of overwriting all the methods on Something’s interface, Because the parent constructor already implements the interface.

If the Controller does not implement an interface method of Something, then T has to implement all of its methods in order to call a method of Something.

If something = new(test.controller) then the Get method in Controller is called.

T can use variables defined in the Controller structure

Empty interface

Using empty interfaces, various types of object storage can be implemented.

A null interface is used to receive any type as a parameter.

package main

import "fmt"

type Dog struct {
    age int
}

type Cat struct{
    weigh float64
}

type Animal1 interface{}// Use a null interface and accept any type as an argument
func info(v interface{})  {
    fmt.Println(v)
}

func main(a)  {
    /* Using null interfaces, you can implement various types of object storage. * /
    d1:= Dog{1}
    d2 := Dog{2}
    c1 :=Cat{3.2}
    c2:=Cat{3.5}

    animals:=[4] Animal1{d1,d2,c1,c2}
    fmt.Println(animals)

    info(d1)
    info(c1)
    info("aaa")
    info(100)

    var i Animal1
    i = d1
    switch m:=i.(type) {
    case Dog:
        fmt.Println(m.age)
    case Cat:
        fmt.Println(m.weigh)
    }
}
Copy the code

Determine the actual type of the interface

Method one:

A can be of any type a.(of a type) Returns two values, inst and OK. Ok means if it is of this type and OK if it is inst is the converted type.

Method 2:

A.(type) Type is the keyword used with switch case. TypeA(a) is the cast.

Example code:

package main

import (
    "math"
    "fmt"
)

type Shape interface {
    area() float64
    peri() float64
}
type Triangle struct {
    a float64
    b float64
    c float64
}

func (t Triangle) peri(a) float64 {
    return t.a + t.b + t.c
}
func (t Triangle) area(a) float64 {
    p := t.peri() / 2
    area := math.Sqrt(p * (p - t.a) * (p - t.b) * (p - t.c))
    return area
}

type Circle struct {
    r float64
}

func (c Circle) peri(a) float64 {
    return 2 * math.Pi * c.r
}
func (c Circle) area(a) float64 {
    return math.Pi * c.r * c.r
}


// Test the function
func testArea(s Shape){ //s = t
    fmt.Println("Area:",s.area())
}
func testPeri(s Shape){
    fmt.Printf("Circumference: %.2f\n",s.peri())
}

// Determine the type
func getType(s Shape){
    A. Return two values, inst and OK. Ok indicates if it is of this type, and OK if it is inst is the converted type. * /
    ifinst,ok := s.(Triangle); ok{ fmt.Println("Is of type Triangle... The three sides are:",inst.a,inst.b,inst.c)
    }else ifinst,ok:=s.(Circle); ok{ fmt.Println("Is of type Circle, and the radius is:",inst.r)
    }else{
        fmt.Println("None of the above is true.")}}//
func getType2(s Shape){
    /* a.(type) Type is the keyword used with switch case TypeA(a) is cast */
    switch inst:=s.(type) {
    case Triangle:
        fmt.Println("The triangle.",inst.a,inst.b,inst.c)
    case Circle:
        fmt.Println("Round.",inst.r)
    }
}

func main(a) {
    t := Triangle{3.4.5}

    testArea(t)
    c := Circle{2.5}
    testPeri(c)

    // Define an array of interface types: Shape, which can store any object of the interface as data.
    var arr[4] Shape
    arr[0] = t
    arr[1] = c
    arr[2] = Triangle{1.2.3}
    arr[3] = Circle{5}

    // Determine the type
    getType(t)
    getType2(c)

}
Copy the code

Running result:

Area:6Circumference:15.71Is of type Triangle... The trilateral is:3 4 5Circle.2.5
Copy the code

Note that an interface object cannot call the properties of an interface implementation object