Ir al tipo de 8 interfaces de aprendizaje de idiomas

3.Go tipos de datos de idioma

En el último artículo, aprendimos sobre los tipos de funciones del lenguaje Go , y este artículo comprende principalmente los tipos de interfaz. Principalmente como sigue:

3.6 Interfaz

Una interfaz de idioma Go está representada por una colección de métodos. Siempre que un tipo de datos (o un tipo de puntero correspondiente al mismo) sea un conjunto adjunto de métodos de un superconjunto de conjunto de métodos de interfaz , entonces se puede determinar que el tipo implementa esta interfaz.

3.6.1 Notación de tipo

La declaración del tipo de interfaz consta de varias declaraciones de método. La declaración del método consta del nombre del método y la firma del método . No se permiten nombres de métodos duplicados en la declaración de un tipo de interfaz.

El tipo de interfaz es el nombre colectivo de todos los tipos de interfaz personalizados. Tomando como ejemplo el tipo de interfaz Interfaz en el orden del paquete de código de biblioteca estándar , la declaración es la siguiente:

type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(I, j int)
}

En el lenguaje Go, un tipo de interfaz se puede incrustar en otro tipo de interfaz. La siguiente declaración de tipo de interfaz:

type Sortable interface {
    sort.Interface
    Sort()
}

El tipo de interfaz anterior Sortable contiene en realidad 4 declaraciones de método, a saber , Len , Less , Swap y Sort .

Go language no proporciona un método típico de subclasificación basada en tipos, pero utiliza este método integrado para lograr el mismo efecto. La incrustación de tipos también incorpora el estilo no incrustado, que también es aplicable a los tipos de estructura que se describen a continuación.

Nota : Un tipo de interfaz solo acepta la incrustación de otros tipos de interfaz.

Con respecto a la incrustación de la interfaz, una restricción es que no se puede incrustar a sí misma , incluida la incrustación directa y la incrustación indirecta .

Incruste directamente de la siguiente manera:

type Interface1 interface {
    Interface1
}

La incrustación indirecta es la siguiente:

type Interface2 interface {
    Interface3
}

type Interface3 interface {
    Interface2
}

La incrustación de interfaz incorrecta provocará errores de compilación. Además, el método declarado en el tipo de interfaz actual no puede tener el mismo nombre que cualquier método del tipo de interfaz incrustado en él, de lo contrario provocará errores de compilación.

En cuanto a un tipo de interfaz especial definido por el lenguaje Go, la interfaz de tipo vacío {} , como se mencionó anteriormente, es una interfaz que no contiene ninguna declaración de método. Además, todos los tipos de datos en el lenguaje Go son sus implementaciones.

3.6.2 Notación de valor

No hay una notación de valor correspondiente para el tipo de interfaz del lenguaje Go, porque la interfaz es una especificación más que una implementación. Sin embargo, a una variable de un tipo de interfaz se le puede asignar el valor de cualquier tipo de datos que implemente este tipo de interfaz, por lo que el valor del tipo de interfaz puede ser representado por el valor de cualquier otro tipo de datos que implemente este tipo de interfaz.

3.6.3 Propiedades y operaciones básicas

El atributo más básico de una interfaz es su colección de métodos.

La implementación de un tipo de interfaz puede ser cualquier tipo de datos personalizado, siempre que el conjunto de métodos adjunto a este tipo de datos sea un superconjunto del conjunto de métodos del tipo de interfaz. Escriba un tipo de datos personalizado SortableStrings , de la siguiente manera:

type SortableStrings [3]string

El tipo de datos personalizado anterior es equivalente a un tipo de alias del tipo de cadena [3] . Ahora, si desea que este tipo de datos personalizado implemente el tipo de interfaz sort.Interface , debe implementar todos los métodos declarados en sort.Interface . La implementación de estos métodos requiere el tipo SortableStrings como tipo de receptor. Las declaraciones de estos métodos son las siguientes:

func (self SortableStrings) Len() int {
    return len(self)
}

func (self SortableStrings) Less(i, j int) bool {
    return self[i] < self[j]
}

func (self SortableStrings) Swap(i, j int) {
    self[i], self[j] = self[j], self[i]
}

Con la declaración de los tres métodos anteriores, el tipo SortableStrings ya es una implementación del tipo de interfaz sort.Interface . Utilice la verificación de expresión de aserción de tipo descrita en la nota 2 de estudio del idioma de Go para escribir el código de la siguiente manera:

_, ok := interface{}(SortableStrings{}).(sort.Interface)

Nota : Para hacer que esta declaración se compile y pase, primero debe importar el tipo de paquete de código estándar.

En el lado derecho de la declaración de asignación anterior hay una expresión de aserción de tipo, y los dos identificadores de la izquierda representan el resultado de la evaluación de esta expresión. Aquí no nos importa el resultado de la conversión, solo si la conversión de tipo es exitosa, por lo que el primer identificador es un identificador vacío "_" ; el segundo identificador ok representa una variable booleana, verdadero significa que la conversión es exitosa, falso significa que la conversión falló. La siguiente figura muestra que el resultado de ok es verdadero , porque el tipo SortableStrings implementa todos los métodos declarados en el tipo de interfaz sort.Interface .

Escriba la descripción de la imagen aquí

Un tipo de interfaz se puede implementar mediante cualquier número de tipos de datos. Un tipo de datos también puede implementar varios tipos de interfaz al mismo tiempo.

El tipo de datos personalizado anterior SortableStrings también puede implementar el tipo de interfaz Sortable . Escriba una declaración de método de la siguiente manera:

func (self SortableStrings) Sort() {
    sort.Sort(self)
}

Ahora, el tipo SortableStrings implementa el tipo de interfaz Sort.Interface al mismo tiempo que el tipo de interfaz Sortable . La expresión de aserción de tipo se verifica de la siguiente manera:

_, ok2 := interface{}(SortableStrings{}).(Sortable)

El resultado de ok2 es verdadero, como se muestra en la siguiente figura:

Escriba la descripción de la imagen aquí

Ahora, el SortableStrings contenía el método Sort de tipo del tipo de destinatario SortableStrings a * SortableStrings , de la siguiente manera:

func (self *SortableStrings) Sort() {
    sort.Sort(self)
}

El tipo de receptor de esta función se ha cambiado al tipo de puntero correspondiente al tipo SortableStrings . El método Sort ya no es un método de valor, se ha convertido en un método de puntero. Solo el valor del puntero correspondiente al valor de SortableStrings puede pasar la aserción de tipo anterior, de la siguiente manera:

_, ok3 := interface{}(&SortableStrings{}).(Sortable)

En este momento , el valor de ok2 es falso y el valor de ok3 es verdadero , como se muestra en la siguiente figura:

Escriba la descripción de la imagen aquí

Luego agregue el siguiente código de prueba:

ss := SortableStrings("2", "3", "1")
ss.Sort()
fmt.Printf("Sortable strings: %v\n", ss)

Para el uso del paquete de código de biblioteca estándar fmt que aparece arriba , puede consultar http://docscn.studygolang.com/pkg/fmt

Los resultados de la prueba son los siguientes:

Escriba la descripción de la imagen aquí

[2, 3, 1] en la información impresa arriba es la representación de cadena del valor del tipo SortableStrings . De los resultados anteriores, podemos ver que el valor de la variable ss no está ordenado, pero se ha llamado al método Sort antes de imprimir .

Escuchemos la explicación a continuación
: Como se mencionó anteriormente, en el método de valor, el cambio en el valor del receptor es invisible fuera del método. El método Sort del tipo SortableStrings en realidad ordena los valores del receptor a través de la función sort.Sort . La función sort.Sort acepta un valor de parámetro de tipo sort.Interface , y usando este método de valor Len , Less y Swap para modificar la ubicación de cada elemento de su argumento para completar el trabajo de clasificación. Para el tipo SortableStrings , aunque implementa todos los métodos declarados en el tipo de interfaz sort.Interface , estos métodos son todos métodos de valor, por lo que el cambio en el valor del receptor en estos métodos no afecta su valor fuente, solo cambia Es solo un copia del valor fuente.

Para el problema anterior, la solución actual es el tipo de método SortableStrings.Los tipos de destinatarios Len , Less e Swap se cambian a * SortableStrings , ejecute la siguiente figura que muestra el resultado de:

Escriba la descripción de la imagen aquí

Pero en este momento, el tipo SortableStrings ya no es la implementación del tipo de interfaz sort.Interface , y * SortableStrings es la implementación del tipo de interfaz sort.Interface . Como se muestra en la figura anterior , el valor de ok es falso .

Ahora consideramos otra solución, cambiando ligeramente la declaración del tipo SortableStrings :

type SortableStrings []string //去掉了方括号中的3

En este momento , el tipo de alias del tipo de matriz de SortableStrings en realidad se cambia al tipo de alias del tipo de segmento , pero hace que los métodos relacionados actuales no puedan compilarse. Los principales errores son los siguientes:

Escriba la descripción de la imagen aquí

Hay dos errores principales que se muestran arriba. Uno es que el parámetro de la función incorporada len no puede ser un valor de tipo de puntero que apunte a un valor de sector; el otro es que las expresiones de índice no se pueden aplicar a un valor de tipo de puntero que apunta a un sector valor.

La siguiente solución a esto es cambiar los tipos de receptor de los métodos Len , Less , Swap y Sort de * SortableStrings de nuevo a SortableStrings . Esto se debe a que el SortableStrings modificado es un tipo de sector y el tipo de sector es un tipo de referencia; para un tipo de referencia , el cambio del método de valor al valor del receptor también se reflejará en su valor de origen. La siguiente figura muestra el resultado modificado:

Escriba la descripción de la imagen aquí

Para el código que aparece en la interfaz anterior, puede hacer clic para descargar el archivo de código fuente de Go , modificarlo usted mismo y experimentar el uso de la interfaz. Solo necesita colocar los siguientes archivos de código fuente en cualquier paquete en el directorio src de su espacio de trabajo (los paquetes son significativos), ingrese la línea de comando e ingrese el comando anterior en el directorio de archivos, por supuesto, en primer lugar su idioma Go variables del entorno Esté bien equipado.

Este artículo se detendrá aquí, y el siguiente artículo continuará con el tipo de datos de idioma Go sin terminar ...

Supongo que te gusta

Origin blog.51cto.com/huazie/2679339
Recomendado
Clasificación