Interfaces en Golang

Las interfaces de idioma de Go son diferentes de otros idiomas. En el lenguaje Go, la interfaz es un tipo personalizado que se utiliza para especificar un conjunto de una o más firmas de métodos y la interfaz es abstracta, por lo que no puede crear una instancia de la interfaz. Pero se le permite crear una variable de un tipo de interfaz y esta variable se puede asignar con un valor de tipo concreto que tenga los métodos que requiere la interfaz. O, en otras palabras, la interfaz es una colección de métodos y también es un tipo personalizado.

¿Cómo crear una interfaz?

En el lenguaje Go, puede crear una interfaz usando la siguiente sintaxis:

type interface_name interface{

// Method signatures

}

Por ejemplo:

// Creating an interface
type myinterface interface{

// Methods
fun1() int
fun2() float64
}

Aquí, el nombre de la interfaz se incluye entre las palabras clave de tipo e interfaz y las firmas del método se incluyen entre llaves.

¿Cómo implementar interfaces?

En el lenguaje Go, es necesario implementar todos los métodos declarados en la interfaz para implementar una interfaz. Las interfaces de lenguaje go se implementan implícitamente. Y no contiene ninguna palabra clave específica para implementar una interfaz como otros idiomas. Como se muestra en el siguiente ejemplo:

Ejemplo:

// Golang program illustrates how
// to implement an interface
package main
  
import "fmt"
  
// Creating an interface
type tank interface {
  
    // Methods
    Tarea() float64
    Volume() float64
}
  
type myvalue struct {
    radius float64
    height float64
}
  
// Implementing methods of
// the tank interface
func (m myvalue) Tarea() float64 {
  
    return 2*m.radius*m.height +
        2*3.14*m.radius*m.radius
}
  
func (m myvalue) Volume() float64 {
  
    return 3.14 * m.radius * m.radius * m.height
}
  
// Main Method
func main() {
  
    // Accessing elements of
    // the tank interface
    var t tank
    t = myvalue{10, 14}
    fmt.Println("Area of tank :", t.Tarea())
    fmt.Println("Volume of tank:", t.Volume())
}

Producción:

Area of tank : 908
Volume of tank: 4396

Puntos importantes

  • El valor cero de la interfaz es nulo.
  • Cuando una interfaz contiene cero métodos, este tipo de interfaz se conoce como interfaz vacía. Entonces, todos los tipos implementan la interfaz vacía.

    Sintaxis:

    interface{}
  • Tipos de interfaz: la interfaz es de dos tipos, una es estática y otra es de tipo dinámico. El tipo estático es la propia interfaz, por ejemplo, tanque en el siguiente ejemplo. Pero la interfaz no tiene un valor estático, por lo que siempre apunta a los valores dinámicos.
    Una variable del tipo de interfaz que contiene el valor del Tipo que implementa la interfaz, por lo que el valor de ese Tipo se conoce como valor dinámico y el tipo es el tipo dinámico. También se conoce como valor concreto y tipo concreto.

    Ejemplo:

    // Go program to illustrate the concept
    // of dynamic values and types
    package main
      
    import "fmt"
      
    // Creating an interface
    type tank interface {
      
        // Methods
        Tarea() float64
        Volume() float64
    }
      
    func main() {
      
        var t tank
        fmt.Println("Value of the tank interface is: ", t)
        fmt.Printf("Type of the tank interface is: %T ", t)
    }

    Producción:

    Value of the tank interface is:  <nil>
    Type of the tank interface is: <nil> 
    

    Aquí, en el ejemplo anterior, tenemos una interfaz denominada tanque. En este ejemplo,
    la instrucción fmt.Println(“El valor de la interfaz del tanque es: “, t) devuelve el valor dinámico de la interfaz y la instrucción fmt.Printf(“El tipo de interfaz del tanque es: %T”, t) devuelve el tipo dinámico, es decir, nil porque aquí la interfaz no sabe quién la está implementando.

  • Aserciones de tipo: en el lenguaje Go, la aserción de tipo es una operación aplicada al valor de la interfaz. O en otras palabras, la aserción de tipo es un proceso para extraer los valores de la interfaz.

    Sintaxis:

    a.(T)

    Aquí, a es el valor o la expresión de la interfaz y T es el tipo también conocido como tipo afirmado. La aserción de tipo se utiliza para verificar que el tipo dinámico de su operando coincida o no con el tipo afirmado. Si la T es de tipo concreto, entonces la aserción de tipo comprueba que el tipo dinámico dado de a es igual a la T, aquí, si la comprobación se lleva a cabo con éxito, entonces la aserción de tipo devuelve el valor dinámico de a. O si la comprobación falla, la operación entrará en pánico. Si T es de un tipo de interfaz, entonces la aserción de tipo verifica que el tipo dinámico dado de a satisface T, aquí, si la verificación se realiza con éxito, entonces el valor dinámico no se extrae.

    Ejemplo:

    // Go program to illustrate
    // the type assertion
    package main
      
    import "fmt"
      
    func myfun(a interface{}) {
      
        // Extracting the value of a
        val := a.(string)
        fmt.Println("Value: ", val)
    }
    func main() {
      
        var val interface {
        } = "GeeksforGeeks"
          
        myfun(val)
    }

    Producción:

    Value:  GeeksforGeeks

    En el ejemplo anterior, si cambiamos esta instrucción val := a.(string) a val := a.(int) , entonces el programa entrará en pánico. Entonces, para superar este problema, usamos la siguiente sintaxis:

    value, ok := a.(T)

    Aquí, si el tipo de a es igual a T, entonces el valor contiene el valor dinámico de a y ok se establecerá en verdadero. Y si el tipo de a no es igual a T, entonces está bien establecido en falso y el valor contiene valor cero, y el programa no entra en pánico. Como se muestra en el siguiente programa:

    Ejemplo:

    // Go program to illustrate type assertion
    package main
      
    import "fmt"
      
    func myfun(a interface{}) {
        value, ok := a.(float64)
        fmt.Println(value, ok)
    }
    func main() {
      
        var a1 interface {
        } = 98.09
      
        myfun(a1)
      
        var a2 interface {
        } = "GeeksforGeeks"
      
        myfun(a2)
    }

    Producción:

    98.09 true
    0 false
    
  • Cambio de tipo: en la interfaz Go, el cambio de tipo se usa para comparar el tipo concreto de una interfaz con los múltiples tipos proporcionados en las declaraciones de caso. Es similar a la aserción de tipo con una sola diferencia, es decir, el caso especifica los tipos, no los valores. También puede comparar un tipo con el tipo de interfaz. Como se muestra en el siguiente ejemplo:

    Ejemplo:

    // Go program to illustrate type switch
    package main
      
    import "fmt"
      
    func myfun(a interface{}) {
      
        // Using type switch
        switch a.(type) {
      
        case int:
            fmt.Println("Type: int, Value:", a.(int))
        case string:
            fmt.Println("\nType: string, Value: ", a.(string))
        case float64:
            fmt.Println("\nType: float64, Value: ", a.(float64))
        default:
            fmt.Println("\nType not found")
        }
    }
      
    // Main method
    func main() {
      
        myfun("GeeksforGeeks")
        myfun(67.9)
        myfun(true)
    }

    Producción:

    Type: string, Value:  GeeksforGeeks
    
    Type: float64, Value:  67.9
    
    Type not found
    
  • Uso de la interfaz: puede usar la interfaz cuando en métodos o funciones desea pasar diferentes tipos de argumentos en ellos, como la función Println(). O también puede usar la interfaz cuando varios tipos implementan la misma interfaz.

Publicación traducida automáticamente

Artículo escrito por ankita_saini y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *