Tipos de datos Personalizados y Métodos en Go (Golang)

in #cervantes6 years ago

gopher wallpaper

Tipos personalizados y métodos en Go (Golang)

Hasta el momento hemos visto y trabajado con algunos tipos primitivos de GO, cómo int, int32, int64, float32, float64, string, bool, con ellos es posible realizar un gran número de operaciones y, en conjunto, programas interesantes. Sin embargo, en ciertas ocasiones pueden no ser suficientes para realizar algunas tareas, veamos cómo abordar estos casos a la manera de Go.

Tipos personalizados.

Exploremos este caso: tenemos un par de variables que almacenan números que representan tiempo en horas y en minutos, deseamos sumarlos para conocer el tiempo total en minutos.

package main

import "fmt"

func main() {
    var tiempoMinutos = 15
    var tiempoHoras = 1
    var tiempoTotal = minutos + horas

    fmt.Println(tiempoTotal) // 16
}



Nada fuera de lo común, ambas variables son de tipo int por lo que pueden sumarse sin problemas y su valor es almacenado en una variable denominada total que también es de tipo int, produciendo como resultado el valor de 16, todo parece funcionar. Pero, en el contexto de nuestro programa, no es correcto que un valor en minutos y otro en segundos se sumen sin más, deberíamos multiplicar tiempoHoras por 60 para producir un resultado en minutos, la verdad es que podríamos realizar esto de forma directa, pero una manera más interesante y elegante podría ser utilizar los tipos personalizados, no tiene nada que ver con el título de esta sección, así que seguro los toma por sorpresa. Veamos el código.

package main

import "fmt"

type minutos int

type horas int

func main() {
    var tiempoMinutos minutos = 15
    var tiempoHoras horas = 1
    var tiempoTotal = tiempoMinutos + tiempoHoras
    // invalid operation: tiempoMinutos + tiempoHoras (mismatched types minutos and horas)

    fmt.Println(tiempoTotal)
}



Ahora tenemos un error, lo cuál es excelente. Conozcamos al recién llegado, la palabra reservada type nos permite declarar nuevos tipos de datos a partir de los existentes, en este caso, horas y minutos son nuevos tipos de datos que parten del tipo int, por lo que podemos aprovechar todas las características del tipo de dato base, y desarrollar algunas nuevas para nuestro tipo personalizado. Veremos más de type en el futuro.

Entendamos primero lo que sucede, aunque ambos valores son enteros, las variables son de tipos diferentes y Go no realiza conversiones implícitas de tipos, debemos ser explícitos. Podemos hacerlo de la siguiente manera var tiempoTotal = tiempoMinutos + minutos(tiempoHoras), pero esto nos regresa al punto de partida, el valor almacenado en la variable tiempoTotal es 16, con la diferencia de que el tipo de dicha variable ahora es minutos. Si se preguntan de que sirvió entonces hacer todo esto, permitan que les diga dos cosas: en primer lugar, me encanta que se hagan preguntas; en segundo, tengan un poco de paciencia, en la siguiente parte cobrará sentido, lo prometo.

Métodos

No voy a detenerme explicar lo que son los métodos, ya que se trata de un concepto bastante conocido en la programación, de todas formas los invito a consultar la siempre útil Wikipedia. A efectos prácticos los métodos son funciones, de hecho, su sintaxis es casi idéntica, su principal diferencia radica en que están ligados a cierta entidad o tipo de dato. Continuemos con el ejemplo anterior para ilustrarlo mejor.

package main

import "fmt"

type minutos int

type horas int

func (h horas) aMinutos() minutos {
    return minutos(h * 60)
}

func main() {
    var tiempoMinutos minutos = 15
    var tiempoHoras horas = 1
    var tiempoTotal = tiempoMinutos + tiempoHoras.aMinutos()

    fmt.Println(tiempoTotal) // 75
}



Ya deben suponerlo, pero aMinutos es un método, el tipo de dato que les cabo de mencionar. Como pueden ver, se trata de una función común y corriente, con excepción del (h horas) que encontramos entre func y el nombre de la función. Esta variable h realmente podría llamarse de cualquier forma, y es lo más cercano a la función de palabras reservadas this o self en otros lenguajes de programación. Permite acceder al valor de la entidad en cuestión. Si les resulta confuso, veamos su comportamiento en nuestro ejemplo y debería quedar más claro.

En primer lugar, func (h horas) aMinutos() minutos es un método del tipo de dato horas, esto lo indicamos con (h horas), teniendo a la derecha el tipo de dato al que está asociado el método y a la izquierda el identificador con el que haremos referencia al valor de este tipo de dato. Como cuerpo del método tenemos return minutos(h * 60), aquí multiplicamos el valor de h por 60 y convertimos el resultado al tipo de dato minutos, que corresponde con el tipo de retorno del método

La otra línea que requiere un explicación es var tiempoTotal = tiempoMinutos + tiempoHoras.aMinutos(); debido a que la variable tiempoHoras es de tipo horas, tiene acceso al método aMinutos a través de la notación de punto, lo que sucede en esta sentencia es que tiempoHoras toma el lugar de h dentro del método aMinutos, su valor se multiplica por 60, transformado el resultado al tipo de dato minutos, por lo que el valor de retorno, que es 60 (1 * 60), se suma con los 15 que almacena la variable tiempoMinutos, siendo ambos valores ahora de tipo minutos, se produce el resultado deseado, 75.

Otros detalles interesantes

Considero importante aclarar que sólo es posible declarar métodos para tipos de datos definidos en el mismo paquete, eso aplica también para los tipos primitivos. Al igual que con las funciones, si se desea modificar el valor de una variable desde el interior de un método, debemos hacer uso de punteros func (t *type) nombreFuncion().

Espero que no les resultara demasiado complejo, la verdad bastante fácil de entender después de realizar algunas prácticas, así que, como siempre, los invito a realizar pruebas por su cuenta, les aseguro que tanto los métodos como los tipos personalizados les resultaran de mucha utilidad y les estaré mostrando próximamente algunos casos de uso.

separator.png

Publicaciones relacionadas

  1. De Python a Go (Golang)

  2. Introducción al lenguaje de programación Go (Golang)

  3. Estructuras de control de flujo en Go

  4. Array y Slice en Go (Golang)

  5. Maps en Go (Golang)

  6. Punteros en Go (Golang)

  7. Importaciones y paquetes en Go (Golang)

  8. Paquetes de terceros y alias 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 dónde compartimos contenido de esa naturaleza y totalmente en español. Hasta la próxima.

banner-steemit.jpg

Sort:  

Este post fue votado por la comunidad y trail @developspanish, comunidad encargada de curar a los programadores, traductores de software y bloggers de informática y tecnología de habla hispana.

¿Quieres recibir mejores recompensas en tus post de informática, tecnología o programación, ayúdanos delegando algo de SP:
1 SP, 5 SP, 10 SP