Getting to Know Go Language 16 - Interface-Oriented Programming [Basic Concepts of Interfaces, Interface Embedding, Empty Interfaces, Type Assertions, Interface-Oriented Programming]


programming to interface

Basic concepts of interfaces

  An interface is a collection of behavior specifications.

type Transporter interface {
    
     //定义接口。通常接口名以er结尾
    //接口里面只定义方法,不定义变量
    move(src string, dest string) (int, error) //方法名 (参数列表) 返回值列表
    whistle(int) int //参数列表和返回值列表里的变量名可以省略
}

  A struct is said to "implement an interface" as long as it has all the methods declared in the interface. A struct can implement multiple interfaces at the same time.

type Car struct {
    
     //定义结构体时无需要显式声明它要实现什么接口
    price int
}

func (car Car) move(src string, dest string) (int, error) {
    
    
    return car.price, nil
}
func (car Car) whistle(n int) int {
    
    
    return n
}

  An interface value consists of two parts, a pointer to the concrete type of the interface and another pointer to the actual data of the concrete type.

car := Car{
    
    "宝马", 100}
var transporter Transporter
transporter = car

insert image description here

use of interface

func transport(src, dest string, transporter Transporter) error {
    
    
	 _,err := transporter.move(src, dest)
	return err
}
var car Car		//Car实现了Transporter接口
var ship Shiper	// Shiper实现了Transporter接口
transport("北京", "天津", car)
transport("北京", "天津", ship)

interface assignment

func (car Car) whistle(n int) int {
    
    }//方法接收者是值
func (ship *Shiper) whistle(n int) int {
    
    } //方法接收者用指针,则实现接口的是指针类型
car := Car{
    
    }
ship := Shiper{
    
    }
var transporter Transporter
transporter = car 
transporter = &car     //值实现的方法,指针同样也实现了
transporter = &ship

interface embedding

type Transporter interface {
    
    
	whistle(int) int
}
type Steamer interface {
    
    
    Transporter //接口嵌入。相当于Transporter接口定义的行为集合是Steamer的子集
    displacement() int
}

empty interface

  The empty interface type is represented by interface{}, pay attention to {}.

var i interface{
    
    } 

  An empty interface does not define any methods, so any type implements the empty interface.

var a int = 5
i = a
func square(x interface{
    
    }){
    
    } //该函数可以接收任意数据类型

  The elements of the slice and the key and value of the map can all be empty interface types. The key in the map can be any type that can be compared with the == operator, and cannot be a function, map, slice, or struct containing member variables of the above 3 types. The value of the map can be of any type.

type assertion

if v, ok := i.(int); ok {
    
    //若断言成功,则ok为true,v是具体的类型
	fmt.Printf("i是int类型,其值为%d\n", v)
} else {
    
    
	fmt.Println("i不是int类型")
}

  When there are many types to be judged, you need to write a lot of if-else. A better way is to use switch i.(type).

switch v := i.(type) {
    
        //隐式地在每个case中声明了一个变量v
case int:  //v已被转为int类型
	fmt.Printf("ele is int, value is %d\n", v)
	//在 Type Switch 语句的 case 子句中不能使用fallthrough
case float64:      //v已被转为float64类型
	fmt.Printf("ele is float64, value is %f\n", v)
case int8, int32, byte: //如果case后面跟多种type,则v还是interface{}类型
	fmt.Printf("ele is %T, value is %d\n", v, v)
}

programming to interface

E-commerce recommendation process
insert image description here

Define an interface for each step.

type Recaller interface {
    
    
    Recall(n int) []*common.Product //生成一批推荐候选集
}
type Sorter interface {
    
    
    Sort([]*common.Product) []*common.Product //传入一批商品,返回排序之后的商品
}
type Filter interface {
    
    
    Filter([]*common.Product) []*common.Product //传入一批商品,返回过滤之后的商品
}
type Recommender struct {
    
    
    Recallers []recall.Recaller
    Sorter sort.Sorter
    Filters []filter.Filter
}

Use pure interface to write recommendation main process.

func (rec *Recommender) Rec() []*common.Product {
    
    
	RecallMap := make(map[int]*common.Product, 100)
	//顺序执行多路召回
	for _, recaller := range rec.Recallers {
    
    
		products := recaller.Recall(10) //统一设置每路最多召回10个商品
		for _, product := range products {
    
    
			RecallMap[product.Id] = product //把多路召回的结果放到map里,按Id进行排重
		}
	}
	//把map转成slice
	RecallSlice := make([]*common.Product, 0, len(RecallMap))
	for _, product := range RecallMap {
    
    
		RecallSlice = append(RecallSlice, product)
	}
	SortedResult := rec.Sorter.Sort(RecallSlice) //对召回的结果进行排序
	//顺序执行多种过滤规则
	FilteredResult := SortedResult
	for _, filter := range rec.Filters {
    
    
		FilteredResult = filter.Filter(FilteredResult)
	}
	return FilteredResult
}

  Interface-oriented programming is all interfaces at the framework level. The specific implementation is done by different developers, and each implementation is put into a go file separately, so that everyone's code does not interfere with each other. It is also convenient to compare the effects by choosing which implementation to use through configuration.

Guess you like

Origin blog.csdn.net/m0_52896752/article/details/130361188