Llegó el momento de pasar a la definición de tipos definidos compuestos, los cuales permitirán componer un tipo de dato compuesto de varios tipos básicos, a modo de registro o de ficha de datos. Go facilita la definición y operación de tipos compuestos mediante estructuras.
Declaración de una estructura
Para definir una estructura, hemos de declarar un tipo definido mediante la palabra clave type
, seguido del nombre que designemos para la estructura y de la palabra clave struct
. Después, hemos de declarar cada uno de los campos de la estructura y su tipo, como si declarásemos variables básicas.
En el siguiente ejemplo, definiremos una estructura llamada Empleado, la cual contendrá los campos nombre, teléfono
y esCasado
.
type Empleado struct { nombre, telefono string esCasado bool }
Una estructura es un tipo definido y no se utiliza directamente, si no que hemos de declarar variables de ese tipo, y utilizar dichas variables para leer y escribir los valores correspondientes. La estructura es como un molde que define la forma que tendrá los objetos que salgan de dicho molde. Estos objetos se denominan instancias.
Creación de instancias
Una instancia es un objeto creado a partir de una estructura. Básicamente, es una variable declarada del tipo de la estructura.
Existen varios métodos de crear y utilizar una instancia. A continuación se explica cada una de ellas.
Declaración simple
La instancia (o variable) se declara en primer lugar. Después se accede, individualmente, a cada uno los campos o propiedades de la estructura.
var empleado1 Empleado empleado1.nombre = "Rafael Hernampérez" empleado1.telefono = "687990033" empleado1.esCasado = true
Para acceder a un campo (ya sea para asignar un valor como para leer su valor), se especifica el nombre de la instancia (variable), seguido de un punto y del nombre del campo o propiedad.
En este aspecto, las estructuras en Go son muy similares a la programación orientada a objetos en otros lenguajes de programación. El concepto aquí, es el uso de estas estructuras como contenedores de datos compuestos.
Declaración y asignación en un paso
En el siguiente ejemplo, se asignan los datos a una estructura en la misma declaración. Para ello, dicha declaración debe realizarse por inferencia, y los valores se pasan como un objeto JSON, al cual hay que anteponer el nombre de la estructura para forzar el casting.
empleado2 := Empleado{ nombre: "Eduardo Fernández", telefono: "677890911", esCasado: false, }
- El casting es un concepto que veremos más adelante en este tutorial. El casting obliga a que el dato o valor sea del tipo especificado. Suele utilizarse para convertir valores entre diferentes tipos, si son compatibles. En este caso, obliga a que los datos tengan la misma estructura que la declarada para la estructura Empleados. Si no es así, se producirá un error.
- Cuando escribimos este tipo de sintaxis, tras el último valor ha de especificarse el cierre de las llaves (
}
), o bien terminar con una coma (como ha sido este caso). Si no se hace así, el compilador de Go da un error: syntax error: unexpected newline, expecting comma or }
Declaración y asignación mediante un puntero
Un puntero es un concepto avanzado que veremos en otro capítulo de este tutorial. Como avance, diremos que los datos son gestionados directamente en la memoria. El puntero apunta a la dirección de la memoria de una variable o instancia. Después, mediante la indirección de memoria, el puntero apuntará o referenciará a la dirección de memoria de un objeto JSON con los datos.
empleado3 := new(Empleado) empleado3 = &Empleado{ nombre: "Sara Connor", telefono: "620990134", esCasado: false, }
Estructuras anónimas
Una estructura anónima es creada y utilizada una única vez, en el mismo momento de declarar la instancia que la utiliza.
rectangulo := struct { alto, ancho float64 }{ alto: 12.5, ancho: 20.8}
Este tipo de estructuras son útiles en casos de un sólo uso, ahorrando tener declaraciones que no se utilizan.
Ejemplo
El siguiente programa repasa todos los conceptos vistos en este capítulo.
package main import "fmt" func main() { // Definicion de la estructura Empleado type Empleado struct { nombre, telefono string esCasado bool } // Metodo 1: declaracion y posterior asignacion var empleado1 Empleado empleado1.nombre = "Rafael Hernampérez" empleado1.telefono = "687990033" empleado1.esCasado = true // Metodo 2: declaracion y asignacion al mismo tiempo empleado2 := Empleado{ nombre: "Eduardo Fernández", telefono: "677890911", esCasado: false, } // Metodo 3: declaracion de un puntero al tipo // La asignacion posterior se realiza con indireccion empleado3 := new(Empleado) empleado3 = &Empleado{ nombre: "Sara Connor", telefono: "620990134", esCasado: false, } fmt.Printf("Empleado 1: %v (%T)\n", empleado1, empleado1) fmt.Printf("Empleado 2: %v (%T)\n", empleado2, empleado2) fmt.Printf("Empleado 3: %v (%T)\n", empleado3, empleado3) // Estructura anonima rectangulo := struct { alto, ancho float64 }{alto: 12.5, ancho: 20.8 } fmt.Printf("rectangulo: %v (%T)\n", rectangulo, rectangulo) }
El resultado es el siguiente:
$ go estructura-datos.go Empleado 1: {Rafael Hernampérez 687990033 true} (main.Empleado) Empleado 2: {Eduardo Fernández 677890911 false} (main.Empleado) Empleado 3: &{Sara Connor 620990134 false} (*main.Empleado) rectangulo: {12.5 20.8} (struct { alto float64; ancho float64 })
Enlaces de interés
- A Tour of Go - Structs: https://tour.golang.org/moretypes/2
- Golang Book - Structs and interfaces: https://www.golang-book.com/books/intro/9
- Go By Example - Structs: https://gobyexample.com/structs
- Golangbot - Structs: https://golangbot.com/structs/
No hay comentarios:
Publicar un comentario