Puede comprender la interfaz Golang de la serie de un vistazo

https://blog.csdn.net/u011957758/article/details/81150622

Prefacio

La interfaz es un movimiento de uso frecuente en la programación orientada a objetos y también es un medio muy importante para reflejar el polimorfismo.
Si. También hay interfaces en Golang.

Este artículo explicará la interfaz de Golang de una manera fácil de entender.

Después de 10 segundos, los siguientes puntos de conocimiento están a punto de llegar al campo de batalla:
1. ¿Por qué necesito una interfaz?
2. ¿Qué es la interfaz? ¿Cómo definir?
3. Primera experiencia de la interfaz en combate real
4. ¿Cómo probar si se ha implementado la interfaz?
5. Interfaz vacía y afirmación de tipo
6. Interfaz de valor cero
7. Un tipo implementa múltiples interfaces
8. La diferencia entre punteros y tipos de valor implementan interfaces
9. Interfaz anidada

texto

1. ¿Por qué necesito una interfaz?

En la mayoría de los casos, los datos pueden contener diferentes tipos, pero hay uno o más puntos en común, y estos puntos en común son la base de la abstracción. La herencia de Golang mencionada anteriormente resuelve el problema de es-un, la relación de herencia única. Pero cuando diferentes clases principales tienen el mismo comportamiento, la herencia única no se puede resolver.

Desde entonces, apareció la interfaz. La interfaz puede entenderse como una abstracción de un cierto aspecto, que puede ser de varios a uno (varios tipos implementan una interfaz), que también es una manifestación de polimorfismo . Resolvió el problema uno a uno anterior.

2. ¿Qué es la interfaz? ¿Cómo definir?

Qué
interfaz es un conjunto que contiene solo el nombre del método, los parámetros, el valor de retorno no es la realización específica del proceso de recolección .

Si se implementan todos los métodos de la interfaz, se considera que la interfaz está implementada y no es necesario agregar una declaración sobre el tipo .

Bajo esta explicación, profundice la impresión de que la interfaz en php se ve así:

//定义接口
interface base{
   public function getName();
}
 
//学生类
class student implements base{
   public function getName(){
      echo "咖啡色的羊驼";
   }
}

Aquí hay una palabra clave: implementos .

Tal declaración se llama explícita y en Golang la interfaz se implementa implícitamente . (Ver más abajo para un presagio)

definición

type interfaceName interface { 
	// 方法列表 
    GetName() string
} 

3. Primera experiencia de combate real de interfaz

En la programación real, a todos les gusta terminar el nombre de la interfaz con er. Por supuesto, esto depende de las preferencias personales.

Código anterior:

	package main

	import (
		"fmt"
	)
	
	// 定义一个接口
	type People interface {
		ReturnName() string
	}
	
	// 定义一个结构体
	type Student struct {
		Name string
	}
	
	// 定义结构体的一个方法。
	// 突然发现这个方法同接口People的所有方法(就一个),此时可直接认为结构体Student实现了接口People
	func (s Student) ReturnName() string {
		return s.Name
	}
	
	func main() {
		cbs := Student{Name:"咖啡色的羊驼"}
	
		var a People
		// 因为Students实现了接口所以直接赋值没问题
		// 如果没实现会报错:cannot use cbs (type Student) as type People in assignment:Student does not implement People (missing ReturnName method)
		a = cbs       
		name := a.ReturnName() 
		fmt.Println(name) // 输出"咖啡色的羊驼"
	}

4. ¿Cómo probar si se ha implementado la interfaz?

Utilice el juicio de afirmación específico de la interfaz para lograr (se mencionará nuevamente a continuación para profundizar la impresión).

Sintaxis: x. (T)
tal gramática solo es adecuada para x es un tipo de interfaz

Siguiendo el ejemplo anterior, continúe con el código:

	// 由于x.(T)只能是接口类型判断,所以传参时候,传入的是接口类型
	// 为何test的类型可以是一个空接口?埋伏笔下文便知。
	func CheckPeople(test interface{}) {
		if _, ok := test.(People); ok {
	    	fmt.Printf("Student implements People")
		}
	}

	
	func main() {
		cbs := Student{Name:"咖啡色的羊驼"}
		CheckPeople(cbs) // Student implements People
	}

5. Interfaz vacía y afirmación de tipo

Interfaz vacía

Una interfaz vacía es una interfaz que no contiene ningún método. Debido a esto, todos los tipos implementan interfaces vacías .

Aunque la interfaz vacía no juega ningún papel, la interfaz vacía es muy útil cuando se necesita almacenar cualquier tipo de valor, esto también responde a la pregunta anterior, ya que la interfaz vacía puede almacenar cualquier tipo de datos.

	// 定义cbs为空接口
    var cbs interface{}
    var i int = 5
    var s string = "Hello world"
    // cbs可以存储任意类型的数值
    cbs = i
    cbs = s

Aserción de tipo

Dado que la interfaz vacía puede almacenar cualquier tipo, ¿cómo distinguir entre diferentes tipos?
Hay dos métodos de uso común: afirmación por coma y juicio de cambio .

Código anterior:

	package main
	
	import (
		"fmt"
	)
	
	// 定义一个结构体
	type Student struct {
		Name string
	}
	
	// 类型断言
	func main() {
	    Params := make([]interface{}, 3)
		Params[0] = 88                   // 整型
		Params[1] = "咖啡色的羊驼"         // 字符串
		Params[2] = Student{Name: "cbs"} // 自定义结构体类型
		
		// Comma-ok断言
		for index, v := range Params {
			if _, ok := v.(int); ok {
				fmt.Printf("Params[%d] 是int类型 \n", index)
			} else if _, ok := v.(string); ok {
				fmt.Printf("Params[%d] 是字符串类型\n", index)
			} else if _, ok := v.(Student); ok {
				fmt.Printf("Params[%d] 是自定义结构体类型\n", index)
			} else {
				fmt.Printf("list[%d] 未知类型\n", index)
			}
		}
		
		// switch判断
		for index, v := range Params {
			switch  value := v.(type) {
	        case int:
	            fmt.Printf("Params[%d] 是int类型, 值:%d \n", index,value)
	        case string:
	            fmt.Printf("Params[%d] 是字符串类型, 值:%s\n", index,value)
	        case Student:
	            fmt.Printf("Params[%d] 是Person类型, 值:%s\n", index,value)
	        default:
	            fmt.Printf("list[%d] 未知类型\n", index)
	        } 
		
		}  
	}

6. Valor cero de la interfaz

El valor cero de la interfaz es nulo

	package main
	
	import (
		"fmt"
	)
	
	type People interface {  
	    GetName() string
	}
	
	// 输出 "cbs is nil 类型"
	func main() {  
	    var cbs People
	    if cbs == nil {
	        fmt.Println("cbs is nil 类型")  
	    }
	}

7. Un tipo implementa múltiples interfaces

	package main
	
	import (
		"fmt"
	)
	
	type People interface {
		ReturnName() string
	}
	
	type Role interface {
		ReturnRole() string
	}
	
	type Student struct {
		Name string
	}
	
	func (s Student) ReturnName() string {
		return s.Name
	}
	
	func (s Student) ReturnRole() string {
		return "学生"
	}
	
	func main() {
		cbs := Student{Name: "咖啡色的羊驼"}
	
		var a People  // 定义a为People接口类型
		var b Role    // 定义b为Role接口类型
		
		a = cbs // 由于Student实现了People所有方法,所以接口实现成功,可直接赋值
		b = cbs // 由于Student实现了Role所有方法,所以接口实现成功,可直接赋值
		
		name := a.ReturnName()
		fmt.Println(name) // 输出"咖啡色的羊驼"
	
		role := b.ReturnRole()
		fmt.Println(role) // 输出"学生"
	}

También explique una cosa: para lograr un cierto tipo de interfaz, puede haber otros métodos. Siempre que la implementación del método incluya la interfaz.

8. La diferencia entre el puntero y la interfaz de implementación del tipo de valor

	package main
	
	import (
		"fmt"
	)
	
	type People interface {
		ReturnName() string
	}
	
	type Student struct {
		Name string
	}
	
	type Teacher struct {
		Name string
	}
	
	func (s Student) ReturnName() string {
		return s.Name
	}
	
	func (t *Teacher) ReturnName() string {
		return t.Name
	}
	
	func main() {
		cbs := Student{Name: "咖啡色的羊驼"}
		sss := Teacher{Name: "咖啡色的羊驼的老师"}
	
		// 值类型
		var a People
		a = cbs 
		name := a.ReturnName()
		fmt.Println(name)
	
		// 指针类型
		// a = sss <- 这样写不行!!!
		a = &sss // 由于是指针类型,所以赋值的时候需要加上&
		name = a.ReturnName()
		fmt.Println(name) // 输出"咖啡色的羊驼的老师"
	}

"a = sss" si escribe así provocará un error:

	cannot use sss (type Teacher) as type People in assignment:
	Teacher does not implement People (ReturnName method has pointer receiver)

Debido a que el puntero del profesor implementa el método ReturnName, el profesor no lo implementa.

9. Anidación de interfaz

Similar a la herencia de interfaz de PHP, Golang también tiene su interfaz anidada.

	package main
	
	import (
		"fmt"
	)
	
	type People interface {
		ReturnName() string
	}
	
	type Role interface {
		People // 接口嵌套
		ReturnRole() string
	}
	
	type Student struct {
		Name string
	}
	
	func (s Student) ReturnName() string {
		return s.Name
	}
	
	func (s Student) ReturnRole() string {
		return "学生"
	}
	
	
	
	func main() {
		cbs := Student{Name: "咖啡色的羊驼"}
		
		var a Role
		a = cbs 
		name := a.ReturnName()
		fmt.Println(name)
	
		role := a.ReturnRole()
		fmt.Println(role) 
	}

Supongo que te gusta

Origin blog.csdn.net/qq_32907195/article/details/112985362
Recomendado
Clasificación