Estructuras: ¿Las Clases de Go (Golang)?
cervantes·@orlmicron·
0.000 HBDEstructuras: ¿Las Clases de Go (Golang)?
 # Estructuras: ¿Las Clases de Go (Golang)? *Es un tema un tanto polémico el hecho de que **Go** sea o no un lenguaje de programación *Orientado a Objetos*, ya lo había mencionado antes, pero considero que lo es, aunque soporta este paradigma de una manera bastante peculiar, puede profundizar un poco consultando [Wikipedia](https://es.wikipedia.org/wiki/Go_(lenguaje_de_programaci%C3%B3n))* ## Estructuras Una estructura es sencillamente una colección de campos. Son lo más parecido a las clases en los lenguajes orientados a objetos tradicionales que encontrarán en **Go** y, en mi opinión, una de las mejores características que nos ofrece el lenguaje. ```go package main import "fmt" type Persona struct { Nombre string Apellido string Edad uint8 } func main() { var p Persona fmt.Println(p) // { 0} } ``` <br /> Sinceramente espero no revivir los traumas universitarios de nadie, pero el ejemplo con `Persona` ya es un clásico cuándo hablamos de Programación Orientada a Objetos. Probablemente noten el parecido con las *clases* de otros lenguajes de programación, de hecho, podemos acceder a los valores de los campos de la estructura a través de la notación de puntos, por ejemplo `Persona.Nombre`. Al igual que con los tipos personalizados que vimos en la [publicación anterior](https://steemit.com/cervantes/@orlmicron/tipos-de-datos-personalizados-y-metodos-en-go-golang), utilizamos la palabra reservada `type` para declarar una estructura, seguida del nombre y el tipo `struct`. Dentro de las llaves establecemos todos los campos de nuestra estructura identificados con el tipo de dato correspondiente en cada caso. Otro detalle importante es que el valor *cero* de una estructura es una colección de los valores *cero* de sus campos, por tal motivo, la impresión de la variable `p` nos muestra dos cadenas vacías y un `0`. Agreguemos algunos valores. ```go ... func main() { var p Persona p.Nombre = "Orlando" p.Apellido = "Monteverde" p.Edad = 26 fmt.Println(p) // {Orlando Monteverde 26} } ``` <br /> Esta vez podemos ver los datos que pasamos a la estructura, también es posible hacerlo esta manera `p = Persona{"Orlando", "Monteverde", 26}`, el resultado sería el mismo. Incluso usando la declaración corta `p := Persona{"Orlando", "Monteverde", 26}` nos ahorramos una línea. Perfecto, ya sabemos como crear estructuras y modificar sus valores, veamos algunas cosas interesantes. ## Métodos En la [publicación anterior](https://steemit.com/cervantes/@orlmicron/tipos-de-datos-personalizados-y-metodos-en-go-golang) conocimos los métodos, así que asumiré que ya todos los conocemos. De la misma forma en la que declaramos métodos para los tipos personalizados, podemos hacerlo para las estructuras. ```go ... func (p Persona) Saludar() { fmt.Printf("Hola, mi nombre es %s %s y tengo %d años\n", p.Nombre, p.Apellido, p.Edad) } func main() { p := Persona{"Orlando", "Monteverde", 26} p.Saludar() Hola, mi nombre es Orlando Monteverde y tengo 26 años } ``` <br /> Sólo con estas *propiedades* y *métodos* es imposible no pensar en *clases*, claro, si vienes de un lenguaje *orientado a objetos*, si no es así, ni te preocupes, **Go** es asombroso y nos hace las cosas sencillas. Vamos a crear método. ```go ... func (p Persona) Cumpleanios() { p.Edad += 1 } func main() { p := Persona{"Orlando", "Monteverde", 26} p.Cumpleanios() p.Saludar() // Hola, mi nombre es Orlando Monteverde y tengo 26 años } ``` <br /> El método pudo llamarse *cumpleaños* porque **Go** trabaja por defecto con *UTF-8*, pero no es recomendable usar tildes o caracteres especiales en los identificadores, de hecho, lo más recomendable es utilizar palabras en inglés, pero intento mantener las cosas lo más simples y comprensibles que pueda. Volviendo al código, nada cambió, aun después de ejecutar el método `Cumpleanios`, la edad continua siendo `26`, si han estado siguiendo esta serie deberían saber la razón, de cualquier forma, la solución está en los *punteros*. Hagamos un par de ajustes al método. ```go … func (p *Persona) Cumpleanios() { (*p).Edad += 1 } ``` <br /> Con esto logramos nuestro propósito, al ejecutar el método `Cumpleanios` la edad de nuestra persona se incrementa en uno. Es importante resaltar los paréntesis en la sentencia `(*p).Edad += 1`, si recuerdan el artículo de [punteros](https://steemit.com/cervantes/@orlmicron/punteros-en-go-golang) sabrán que el asterisco antes de la una variable de tipo *puntero* nos permite acceder a su valor y para aplicar esto en las estructuras requerimos los paréntesis, sin embargo, esta sintaxis no es muy práctica y **Go** nos permite el mismo resultado de esta manera `p.Edad += 1`, mucho mejor. ## Campos anónimos En **Go** no existe la **herencia** como en otros lenguajes orientados a objetos, sin embargo, muchas veces tendremos estructuras que comparten características con otras, pero claro, las personas detrás de este lenguaje ya pensaron es esto, y lo solucionaron de una manera bastante sencilla. Partiendo del ejemplo anterior, si ahora creamos una nueva estructura a la que llamaremos `Programador` y como los programadores somos personas, o eso me han contado, sería práctico tomar las características de la estructura `Persona` en lugar de reescribirlas en la nueva estructura. Veamos el código. ```go package main import "fmt" type Persona struct { Nombre string Apellido string Edad uint8 } type Programador struct { Persona Especialidad string LenguajesFavoritos []string } func (p Persona) Saludar() { fmt.Printf("Hola, mi nombre es %s %s y tengo %d años\n", p.Nombre, p.Apellido, p.Edad) } func (p *Persona) Cumpleanios() { p.Edad += 1 } func (p Programador) beberCafe() { fmt.Println("¡Me siento vivo!") } func main() { p := Programador{ Persona{"Orlando", "Monteverde", 26}, "Desarrollo Web", []string{"Go", "Python", "JavaScript"}, } p.Cumpleanios() p.Saludar() // Hola, mi nombre es Orlando Monteverde y tengo 27 años p.beberCafe() // ¡Me siento vivo! fmt.Println(p.Persona) // {Orlando Monteverde 27} fmt.Println(p) // {{Orlando Monteverde 27} Desarrollo Web [Go Python JavaScript]} } ``` <br /> Si quiero que `Programador` comparta los campos y métodos de `Persona` es suficiente con introducir `Persona` como un campo de la estructura `Programador`, no ser podría ser más sencillo. Este es un campo anónimo porque efectivamente no tiene nombre, pero podemos acceder a él de igual forma que al resto de los campos, por medio de la notación de punto. Esta publicación ya se ha hecho bastante larga, aún quedan detalles por tratar sobre las estructuras pero continuaremos trabajando con ellas en el futuro, de hecho ha sido difícil realizar muchos de los ejemplos anteriores sin involucrar a las estructuras. <center></center> ## Publicaciones relacionadas 1. [De Python a Go (Golang)](https://steemit.com/cervantes/@orlmicron/de-python-a-go-golang) 2. [Introducción al lenguaje de programación Go (Golang)](https://steemit.com/cervantes/@orlmicron/introduccion-al-lenguaje-de-programacion-go-golang) 3. [Estructuras de control de flujo en Go](https://steemit.com/cervantes/@orlmicron/estructuras-de-control-de-flujo-en-go) 4. [Array y Slice en Go (Golang)](https://steemit.com/cervantes/@orlmicron/array-y-slice-en-go-golang) 5. [Maps en Go (Golang)](https://steemit.com/cervantes/@orlmicron/maps-en-go-golang) 6. [Punteros en Go (Golang)](https://steemit.com/cervantes/@orlmicron/punteros-en-go-golang) 7. [Importaciones y paquetes en Go (Golang)](https://steemit.com/cervantes/@orlmicron/importaciones-y-paquetes-en-go-golang) 8. [Paquetes de terceros y alias en Go (Golang)](https://steemit.com/cervantes/@orlmicron/paquetes-de-terceros-y-alias-en-go-golang) 9. [Tipos de datos Personalizados y Métodos en Go (Golang)](https://steemit.com/cervantes/@orlmicron/tipos-de-datos-personalizados-y-metodos-en-go-golang) Gracias por leer, espero que este artículo te resultara de provecho. Si así fue, no dudes en dejar un **comentario**, **compartirlo** y **votar**. Te invito a comentar cualquier **duda** o **sugerencia**, te aseguro que las leo todas. Así que, por favor, ayúdame a mejorar y continuar compartiendo contenido de calidad. Si te gusta la programación y/o la informática en general, te invito a formar parte de la comunidad [Develop Spanish](https://discordapp.com/invite/8cFAFTZ) dónde compartimos contenido de esa naturaleza y totalmente en español. Hasta la próxima. 
👍 orlmicron, flipe, shadowmyst, developspanish, belial2412, juancrdrums, reonfi, isther69, shidofuyuki, steemstem, justtryme90, alexzicky, stem.witness, borislavzlatanov, wildtrader, nicholaspang, paddlereunion, traviseric, alexworld, steemitbuzz, liameth, suesa, erh.germany, mahdiyari, de-stem, kevinwong, lemouth, foundation, kryzsec, helo, alexander.alexis, fancybrothers, howo, himal, sco, adetola, rharphelle, lianaakobian, effofex, osariemen, javier.dejuan, lamouthe, tsoldovieri, felixrodriguez, fbslo, tfcoates, robotics101, terrylovejoy, kingabesh, derbesserwisser, temitayo-pelumi, reyvaj, rachelsmantra, kerriknox, bistonic, rockeynayak, gra, sci-guy, mountain.phil28, amavi, croctopus, tombstone, arconite, monie, lesmouths-travel, steemzeiger, biomimi, kenadis, fredrikaa, abigail-dantes, lesshorrible, zeeshan003, azman, dexterdev, serylt, fanta-steem, zest, cryptoitaly, outtheshellvlog, stayoutoftherz, drsensor, robertbira, kelos, langford, vanessahampton, gapalmero, lafona-miner,