En el post previo hablamos de las operaciones básicas con estructuras; como crear ,instanciar y/o asignar valores, en esta entrada veremos operaciones mas avanzadas que podemos realizar con las estructuras.
Estructuras Anidadas
Las estructuras son anidadas cuando agregamos un campo de tipo Estructura dentro de otra Estructura. Es de mucha ayuda anidar estructuras cuando necesitamos crear modelos complejos.
Veamos un ejemplo:
package main import "fmt" //Declaramos la estructura que anidaremos type Club struct { Nombre string Temporadas int } //Declaramos la estructura principal type Jugador struct { Nombre, Posicion string Edad int //Realizamos un slice de la estructura Club Clubes []Club } func main() { //creamos una instancia de la estructura jugador j := Jugador{ Nombre: "Critiano Dos Santos", Posicion: "Delantero", Edad: 36, //agregamos elementos al slice de la estructura club Clubes: []Club{ Club{ Nombre: "Lisboa", Temporadas: 2, }, Club{ Nombre: "Manchester", Temporadas: 6, }, Club{ Nombre: "Madrid", Temporadas: 6, }, }, } fmt.Println(j.Nombre, j.Posicion) //imprimimos los elementos del slice clubes fmt.Println(j.Clubes[0]) fmt.Println(j.Clubes[1]) fmt.Println(j.Clubes[2]) }
Agregar Etiquetas en los campos de la Estructura
El uso de las etiquetas dentro de la definición de cada campo es un concepto sumamente importante, de esta manera cuando estemos trabajando con otros formatos como JSON o XML entre otros, nos facilitará la conversión(mapeo) de objetos en otro formato a nuestra estructura. Las etiquetas se agregan con los caracteres ` después del tipo de dato, estas etiquetas no interfieren en la ejecución del código.
Veamos un ejemplo donde simulamos la conversión de un objeto json a una estructura.
package main import ( "encoding/json" "fmt" ) type Cantante struct { //agregamos las etiquetas despues del tipo de dato Nombre string `json:"nombre"` Grupo string `json:"grupo"` } func main() { //simulamos un objeto json, con una variable string json_string := ` { "nombre": "Nicky Sixx", "grupo": "Motley Crew" }` //creamos un objeto de tipo cantante cantante1 := new(Cantante) //con la función unmarshal vertimos el contenido del json al objeto cantante json.Unmarshal([]byte(json_string), cantante1) fmt.Println(cantante1) cantante2 := new(Cantante) cantante2.Nombre = "Freddy Mercury" cantante2.Grupo = "Queen" //con la función marshal creamos un objeto json apartir de un objeto cantante jsonStr, _ := json.Marshal(cantante2) fmt.Printf("%s\n", jsonStr) }
Agregar Métodos a una Estructura
Es posible agregar métodos a las estructuras, usando un receptor de método (method receiver). Agregaremos un método llamado JugadorDetalle a la estructura Jugador.
package main import "fmt" //Declaramos la estructura que anidaremos type Club struct { Nombre string Temporadas int } //Declaramos la estructura principal type Jugador struct { Nombre, Posicion string Edad int //Realizamos un slice de la estructura Club Clubes []Club } //Creamos una función con el receiver (j Jugador) con lo cual el método //es agregado a la estructura Jugador func (j Jugador) JugadorDetalle() string { fmt.Println(j.Nombre, j.Posicion) fmt.Println(j.Edad) for _, detalle := range j.Clubes { fmt.Println("*********CLUB*******") fmt.Println(detalle.Nombre) fmt.Println(detalle.Temporadas) } return "*********CLUB*******" } func main() { //creamos una instancia de la estructura jugador j := Jugador{ Nombre: "Critiano Dos Santos", Posicion: "Delantero", Edad: 36, //agregamos elementos al slice de la estructura club Clubes: []Club{ Club{ Nombre: "Lisboa", Temporadas: 2, }, Club{ Nombre: "Manchester", Temporadas: 6, }, Club{ Nombre: "Madrid", Temporadas: 6, }, }, } //invocamos el método JugadorDetalle fmt.Println(j.JugadorDetalle()) }
Copiar una Estructura mediante Valor y Apuntador
Cuando copiamos una estructura por valor , cualquier cambio realizado en la copia no afectara al objeto original y viceversa. A diferencia de cuando realizamos una copia por referencia usando &, cualquier campo en la copia será actualizado en el original.
package main import "fmt" type cuadrado struct { lado float64 color string } func main() { //creamos un objeto de tipo cuadrado c1 := cuadrado{40, "Azul"} fmt.Println(c1) //creamos una copia por valor de c1 c2 := c1 //actualizamos el valor de color c2.color = "Rojo" fmt.Println(c2) //creamos una referencia a c1 c3 := &c1 //actualizamos el valor de color c3.color = "Amarillo" //como vemos la copia afectó a la copia y al valor referenciado fmt.Println(c3) fmt.Println(c1) }
Hemos llegado al final del manejo de estructuras, desde realizar operaciones básicas a trabajar con tags, ahora que conocemos el manejo y trato de estructuras en golang podemos implementar estructuras en nuestras aplicaciones.