Structs en Go: Creación y Uso de Atributos y Métodos
Resumen
¿Qué es un struct en Go?
La programación orientada a objetos (OOP) es una práctica común en muchos lenguajes de programación. Uno de los pilares de la OOP son las clases, las cuales están compuestas por atributos y métodos que permiten la interacción con los objetos. Sin embargo, Go, con su simplicidad y eficiencia, no utiliza clases, sino una estructura alternativa llamada struct. Esta herramienta poderosa y versátil permite la creación de estructuras de datos más simples pero igualmente efectivas. En este contenido, exploraremos cómo funcionan los structs y cómo pueden ser útiles para tus proyectos en Go.
¿Cómo crear un struct en Go?
Para crear un struct en Go, se utiliza la palabra clave type seguida del nombre que deseas dar al struct, y a continuación la palabra clave struct. Vamos a ver esto con un ejemplo paso a paso.
type Car struct{ Brand string Model int}
Aquí, hemos creado una estructura Car con dos atributos: Brand de tipo string y Model de tipo int. Estos atributos se asemejan a las propiedades que definirías en una clase dentro de un lenguaje orientado a objetos tradicional.
¿Cómo instanciar un struct?
Una vez definido un struct, hay varias formas de instanciarlo. Comencemos con la forma más directa:
Instanciación directa
myCar := Car{ Brand:"Ford", Model:2020,}
En este ejemplo, instanciamos un objeto Car asignando valores directos a los atributos Brand y Model. Este método se asemeja a crear un objeto y asignar valores en lenguajes como Java o Python.
Instanciación por declaración
Otra forma de crear una instancia de un struct es mediante la declaración inicial sin asignar valores:
var anotherCar Car
anotherCar.Brand ="Ferrari"
Aquí se crea anotherCar sin valores iniciales. Posteriormente, se asigna el valor al atributo Brand. Si se imprime este struct, el atributo Model mostrará un valor por defecto de cero, debido a que Go asigna cero en campos numéricos no inicializados, tal como lo explora el tema de "zero values".
¿Cuál es la utilidad de los structs en Go?
Los structs no solo ofrecen una forma eficiente de agrupar datos relacionados, sino que también permiten:
Extensibilidad: Puedes agregar nuevas propiedades sin cambiar la lógica básica del programa.
Métodos asociados: En futuras lecciones también aprenderás cómo agregar métodos a los structs, ampliando su funcionalidad y permitiendo el encapsulamiento de comportamiento junto a los datos.
Puedes incluso personalizar tus structs para que reflejen con más precisión las características que te interesan, como agregar el color del carro o el tipo de motor.
¿Cómo podrías seguir desarrollando un struct?
El potencial de un struct crece a medida que avanzas en tus habilidades con Go. Un ejercicio útil es imaginar cómo mejorar tus structs con atributos adicionales:
Color: Añadir un atributo que indique el color del carro.
EngineType: Saber si es eléctrico, híbrido o de combustión interna.
Owner: Incluir información sobre el propietario del carro.
Por ejemplo:
type Car struct{ Brand string Model int Color string EngineType string Owner string}
Esta ampliación refleja cómo los structs pueden adaptarse a las necesidades cambiantes y específicas de tu aplicación. ¡No dudes en experimentar y explorar todas las capacidades que Go ofrece con los structs!
Invito a todos los estudiantes a compartir sus ideas y propuestas sobre cómo personalizar sus structs en la sección de comentarios. La práctica es el mejor camino hacia la maestría, ¡continúen aprendiendo y explorando!
same feeling here, ayuda mucho saber python y C a la hora de tomar este curso siento que va muy fluido
Sobre la definición, un struct es simplemente una colección de campos.
Estas fueron algunas cosas que se me ocurrieron agregarle 👇
package main
import"fmt"type car struct { brand string
year int
seating int
color string
owner string
}func main(){myCar:= car{brand:"Toyota",year:2018,seating:10,color:"Rojo",owner:"Eliaz Bobadilla"} fmt.Println("Los Datos de mi auto son:", myCar)
Esto esta mas documentado aquí.
Clase en código enchulado:
package main
import"fmt"type car struct { brand string
year int
}func main(){ fmt.Println() fmt.Println("=======") fmt.Println("STRUCTS") fmt.Println("=======") fmt.Println() fmt.Println("En otros lenguajes existe la estructura llamada Clase, donde se definen atributos y métodos. ") fmt.Println("En Go no existe esta estructura pero ofrece 'structs' que según tiene mas poder.") fmt.Println() fmt.Println("Declaración:") fmt.Println("------------") fmt.Println() fmt.Println("Se declara como otro bloque de función, pero cambiando func por 'type' y luego del nombre se coloca 'struct'") fmt.Println("type car struct { ... }") fmt.Println() fmt.Println("se declaran sus atributos como pares nombre-tipo, uno por línea, tal cual como en el código de este archivo.") fmt.Println("atributico string") fmt.Println() fmt.Println("Primera forma de instanciación:::") fmt.Println("---------------------------------") fmt.Println()myCar:= car{brand:"Renault",year:2021} fmt.Println("myCar := car{brand: \"Renault\", year: 2021}") fmt.Println() fmt.Println("FMT Imprime: ") fmt.Println(myCar) fmt.Println() fmt.Println("Otra forma de imprimirlo en consola:") fmt.Printf("Structsito = %+v", myCar) fmt.Println() fmt.Println() fmt.Println("Instanciación como una clase vacía:") fmt.Println("-----------------------------------") fmt.Println("") fmt.Println("Se intancia así: ") fmt.Println("var otherCar car") fmt.Println() fmt.Println("Y se va asignando los valores de cada atributo:") fmt.Println("otherCar.brand = \"Chevrolet\"") fmt.Println()var otherCar car
otherCar.brand="Chevrolet" fmt.Println("Si un atributo del struct no se inicializa, toma un Zero Value, y por lo tanto se imprime así lo referente al año:") fmt.Println(otherCar) fmt.Println() fmt.Println()}
Metodos jeje
package main
type Person struct { name string
last string
phoneNumber uint32
}func(p Person)getName() string {return p.name}func main(){daniel:=Person{name:"Daniel",last:"Franc",phoneNumber:4061022,}println(daniel.last) daniel.last="Franco"println(daniel.last)println(daniel.getName())}
Usar ese tipo de fuentes en el código hace que sea más difícil de leer
Me gusta mucho la fuente y el juego de colores!
Mis apuntes:
Structs GoForProgrammers
Introduction
A struct (short for "structure") is a collection of data fields with declared data types. Golang has the ability to declare and create its own data types by combining one or more types, including both built-in and user-defined types. Each data field in a struct is declared with a known type, which could be a built-in type or another user-defined type.
Structs are the only way to create concrete user-defined types in Golang. Struct types are declared by composing a fixed set of unique fields. Structs can improve modularity and allow for the creation and passing of complex data structures around the system. You can also consider Structs as a template for creating a data record, like an employee record or an e-commerce product.
The declaration starts with the keyword type, then a name for the new struct, and finally the keyword struct. Within the curly brackets, a series of data fields are specified with a name and a type.
package main
import"fmt"//STRUCTStype person struct{ name string lastname string age int cristian bool}funcmain(){//Instancing me := person{name:"David", lastname:"Olivos", age:15, cristian:true} fmt.Println(me)//Another way of instancingvar otherPerson person
otherPerson.name ="Jonathan" otherPerson.lastname ="Ramirez" fmt.Println(otherPerson)}
Gracias!
Hincapié
Si es que así les resulta largo:
type usuario struct{ nombre string edad int dni int sexo string}
Intente compactar así:
type usuario struct{ nombre, sexo string edad, dni int}
los struct por convención deben comenzar en mayuscula, solo tengalo en cuenta
Por lo que veo son miembros publicos por defecto, como las structs de C++
Si ya sabes lenguajes como C o incluso Typescript, esto va a ser muy familiar 😅
struct dentro de struct
type anotherStruct struct { val string
}type Car struct { brand string
year uint16
model string
subClass anotherStruct
}func StructingBabyyyy(){ferrari:=Car{brand:"Ferrari",year:2020,model:"Roma",subClass: anotherStruct{val:"coupe",}}ford:=Car{brand:"Ford"} fmt.Println(ferrari) fmt.Println(ford)}
Recordando un poco el significado de OOP:
Recordemos que los structs que creemos son moldes, como por ejemplo cada coche tiene una marca, tiene un color, tiene un año etc.
Dentro del molde está el pastel y cada pastel va a ser diferente, o de manera más técnica, cada instance será diferente. Al final la clase/struct es la misma, tendremos un molde de un coche y cambiará dependiendo de las variables que mandemos.
OOP es state y behaviour:
state: Son los datos
behaviour: Son los métodos que podemos poner dentro de una clase
car
package main
import"fmt"type car struct{ brand string model string year int color string}funcmain(){ myCar := car{brand:"Ford",model:"Bronco sport", year:2022, color:"Black"} fmt.Println(myCar)//Otra maneravar otherCar car
otherCar.brand ="Ferrari" fmt.Println(otherCar)}//Impresiones//{Ford Bronco sport 2022 Black}//{Ferrari 0 }
Experimento
type car struct { brand string
year int
countGas func()}func main(){var otherCar = car{} otherCar.brand="Chevrolette" otherCar.countGas=func(){ fmt.Println("Gas","54")} fmt.Println(otherCar) otherCar.countGas()}
Funcionó
Presento una pequeña idea de la mayor cantidad de características que se le puede sacar a la clase Carro:
packagemainimport"fmt"type car struct { brand string // Ford, Renault, Toyota model string // Mustang, Logan, Corolla year int// 2024, 98, 2001 color string // Blanco, Negro, Gris, Plata vin string // 1G1GC12A301234567 mileage float64 // 0.0 km, 1000.00 km engineType string // gasolina, diésel, eléctricos e híbridos numberOfDoors int// 2, 3, 4 o 5 puertas fuelLevel float64 // 0.0, 0.5, 0.75, 0.625 de la capacidad total isElectric bool // de Motor eléctrico o de Gasolina isRunning bool // Está encendido, se agrega una característica más de comportamiento horsePower int// 100, 140, 840, 1200 CV transmissionType string // Manual, Automática, Continuamente Variable (CVT), Doble Embrague (DCT) bodyType string // Sedan, SUV, Coupe, Hatchback, Convertible, Minivan, Pickup, Comerciales fuelType string // Gasolina, Diesel, Electrico, Hibrido seatingCapacity int// Capacidad segura de pasajeros 5, 7, 15 driveTrain string // FWD, RWD, AWD, 4x4(4WD) features []string // Sunroof (Techo Corredizo), LeatherSeats (Asientos de Piel), NavigationSystem (Sistema de navegación), BackupCamera (Cámara de Reversa) isSportsCar bool // Es un carro deportivo? Con características de alto rendimiento maximumSpeed float64 // 180 - 220 - 300 - 500 km/h}func main(){ myCar := car{brand:"Ford", year:2020}fmt.Println(myCar)//Otra maneravar otherCar car
otherCar.brand ="Ferrari" otherCar.model ="SF90 Stradale" otherCar.year =2026 otherCar.color ="Rojo" otherCar.vin ="ZFF65LJA5A0819156" otherCar.mileage =0.0 otherCar.engineType ="Híbrido" otherCar.numberOfDoors =2 otherCar.fuelLevel =0.0 otherCar.isElectric =true otherCar.isRunning =true otherCar.horsePower =1000 otherCar.transmissionType ="Automática" otherCar.bodyType ="Convertible" otherCar.fuelType ="Híbrido" otherCar.seatingCapacity =2 otherCar.driveTrain ="AWD" featuresFerrariSF90Stradale :=[]string{"Sunroof","LeatherSeats","NavigationSystem","BackupCamera"} otherCar.features =append(otherCar.features, featuresFerrariSF90Stradale...) otherCar.isSportsCar =true otherCar.maximumSpeed =330.0fmt.Println(otherCar)}
Esas fueron algunas de las características que le pude encontrar a un Carro.
¿Por buena practica los strucs deberian de ir con la primera letra de la clase en mayusculas como en la mayoria de los lenguajes?
En la siguiente clase se responde mi pregunta jajaja, minúsculas en la primera letra para funciones y clases cuando van a ser privadas, mayúscula cuando van a ser publicas
Exacto ! hay que tener cuidado con eso, lo mas comun es que sean publicos los modelos (structs) porque puede pasar que tengas una variable de tipo "user" por ejemplo este como privada y la pases a una funcion que esta definida en otro paquete y despues no sepas porque se te rompe el programa. Cuando llega a la funcion resulta que no es visible en ese paquete porque es privada solo para el paquete donde fue definida.. me ha dado bastantes dolores de cabeza cuando recien empece con Go esas cosas. Excepto que sepas que el struct lo vas a usar exclusivamente en el paquete donde lo estas definiendo, ahi si podria ser privado. Lo mas normal es que sea publico.
Es necesario saber mucho python o c, para empezar con Go?
Para nada, pero te ayuda algo siempre cuando ya sabes otro lenguaje programación para el tema de definiciones.
cómo agrego valores a un slice, propiedad de un struct
!image
// CLASE 21package main
import"fmt"// Structs es la forma de hacer clases en Go, pero estás tienen más poder, es más podeeeer!!type car struct { brand string
year int
color string
precio int
moneda string
fuenteDeEnergia string
}func main(){myCar:= car{brand:"Ford",year:2020,color:"Black",precio:200000,moneda:"MXN",fuenteDeEnergia:"Electrico"} fmt.Println(myCar)// Otra maneravar otherCar car
otherCar.brand="Ferrari" otherCar.color="Silver" fmt.Println(otherCar)// El 0 es por default para int y espacio vacio es el default para strings cuando no tienen ningun dato}