26 - Estructura de datos tipo structs

Un struct (registro) es una estructura de datos que permite almacenar un conjunto de elementos no necesariamente del mismo tipo.

Vimos que los arrays y slices son estructuras de datos que permiten almacenar un conjunto de datos del mismo tipo.

Un registro normalmente almacena un conjunto de datos que están relacionados entre si.

Ejemplos de registros podrían ser los datos de un alumno (nro de legajo, apellido y nombre, carrera que cursa), una historia clínica de un paciente (nro de documento, obra social que tiene, enfermedades), etc.

A un array o slice accedemos a sus elementos por medio de subíndices, a los elementos de un registro se los llama campos y tienen cada uno un nombre.

Por ejemplo si definimos el registro "producto" sus campos pueden ser el "codigo","descripcion" y "precio".

A diferencia de arrays y slices los registros deben declararse y luego definir variables de dicho tipo.

Veamos la sintaxis para declarar un registro en el lenguaje Go:

type Producto struct {
    codigo int
    descripcion string
    precio float64
}

Hemos declarado un registro llamado "Producto" con tres campos uno de tipo int llamado codigo, otro de tipo string llamado descripcion y finalmente el campo "precio" de tipo float64.

Como vemos los tres campos están relacionados y hacen referencia a las características que puede tener todo producto que vende una empresa.

Pero si solo declaramos el registro no nos sirve de nada, debemos definir una o más variables de dicho tipo.

Hay varias formas de definir variables de tipo producto:

  • Definición de dos registros y carga de datos en uno de ellos por asignación:
    var producto1, producto2 Producto
    producto1.codigo = 1
    producto1.descripcion = "peras"
    producto1.precio = 43.30
    
  • Definición e inicialización de un registro y todos sus campos:
        producto3 := Producto{1, "papas", 12.50}
    
  • Definición e inicialización de un registro y algunos sus campos:
        producto4 := Producto{descripcion:"manzanas", precio:23}
    

Problema 1:

Declarar un registro que permita almacenar el codigo, descripcion y precio de un producto. Luego definir dos variables de dicho tipo, cargarlas por teclado e imprimir el nombre del producto que tiene mayor precio.

Programa: ejercicio125.go

package main

import "fmt"

type Producto struct {
    codigo int
    descripcion string
    precio float64
}

func main() {
    var producto1, producto2 Producto
    fmt.Print("Ingrese el codigo del producto:")
    fmt.Scan(&producto1.codigo)
    fmt.Print("Ingrese la descripcion:")
    fmt.Scan(&producto1.descripcion)
    fmt.Print("Ingrese el precio:")
    fmt.Scan(&producto1.precio)
    fmt.Print("Ingrese el codigo del producto:")
    fmt.Scan(&producto2.codigo)
    fmt.Print("Ingrese la descripcion:")
    fmt.Scan(&producto2.descripcion)
    fmt.Print("Ingrese el precio:")
    fmt.Scan(&producto2.precio)
    if producto1.precio > producto2.precio {
        fmt.Print("El producto ", producto1.descripcion, " tiene un precio mayor")
    } else {
        if producto2.precio > producto1.precio {
            fmt.Print("El producto ", producto2.descripcion, " tiene un precio mayor")
        } else {
            fmt.Print("Tienen igual precio")
        }
    }    
}

Al declarar el struct fuera de la main podemos definir eventualmente variables de este tipo en otras funciones.

Para definir dos variables de tipo "Producto":

    var producto1, producto2 Producto

Cada una de las variables producto1 y producto2 reserva espacio para almacenar tres campos cada una.

Para cargar la variable producto1 debemos ingresar por teclado campo a campo:

    fmt.Print("Ingrese el codigo del producto:")
    fmt.Scan(&producto1.codigo)
    fmt.Print("Ingrese la descripcion:")
    fmt.Scan(&producto1.descripcion)
    fmt.Print("Ingrese el precio:")
    fmt.Scan(&producto1.precio)

Es decir primero indicamos el nombre de la variable "producto1" y seguidamente el campo que estamos cargando "codigo".

La carga del segundo registro llamado producto2 es idéntico a la carga del primer registro:

    fmt.Print("Ingrese el codigo del producto:")
    fmt.Scan(&producto2.codigo)
    fmt.Print("Ingrese la descripcion:")
    fmt.Scan(&producto2.descripcion)
    fmt.Print("Ingrese el precio:")
    fmt.Scan(&producto2.precio)

Para verificar cual de los dos productos tiene un precio mayor debemos acceder al campo precio de cada uno de los dos productos:

    if producto1.precio > producto2.precio {

Lo mismo cuando procedemos a imprimir la descripción por pantalla debemos indicar el campo:

        fmt.Print("El producto ", producto1.descripcion, " tiene un precio mayor")

Tener en cuenta que si pasamos el nombre de la variable producto1 sin indicar un campo la función Print muestra los contenidos de todos los campos:

fmt.Print(producto1)

Problema propuesto

  • Se tiene la siguiente declaración de registro:
    type Pais struct {
        nombre string
        cantidadhab int
    }
    
    Definir tres variables de tipo país y almacenar los nombres de los países y la cantidad de habitantes de dichos países.
    Mostrar seguidamente el nombre del país con mayor cantidad de habitantes (considerar que los tres países tienen cantidades distintas)
Solución
ejercicio126.go

package main

import "fmt"

type Pais struct {
    nombre string
    cantidadhab int
}

func main() {
    var pais1, pais2, pais3 Pais
    fmt.Print("Ingrese el nombre del pais:")
    fmt.Scan(&pais1.nombre)
    fmt.Print("Ingrese la cantidad de habitantes:")
    fmt.Scan(&pais1.cantidadhab)
    fmt.Print("Ingrese el nombre del pais:")
    fmt.Scan(&pais2.nombre)
    fmt.Print("Ingrese la cantidad de habitantes:")
    fmt.Scan(&pais2.cantidadhab)
    fmt.Print("Ingrese el nombre del pais:")
    fmt.Scan(&pais3.nombre)
    fmt.Print("Ingrese la cantidad de habitantes:")
    fmt.Scan(&pais3.cantidadhab)
    if pais1.cantidadhab > pais2.cantidadhab && pais1.cantidadhab > pais3.cantidadhab {
        fmt.Print("Pais con mayor cantidad de habitantes:", pais1.nombre)
    } else {
        if pais2.cantidadhab > pais3.cantidadhab {
            fmt.Print("Pais con mayor cantidad de habitantes: ", pais2.nombre)
        } else {
            fmt.Print("Pais con mayor cantidad de habitantes: ", pais3.nombre)
        }
    }
}