<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ go - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Descubre miles de cursos de programación escritos por expertos. Aprende Desarrollo Web, Ciencia de Datos, DevOps, Seguridad y obtén asesoramiento profesional para desarrolladores. ]]>
        </description>
        <link>https://www.freecodecamp.org/espanol/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ go - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 19:55:21 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/tag/go/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Cómo realizar migraciones de base de datos usando go-migrate ]]>
                </title>
                <description>
                    <![CDATA[ Desde su introducción, el lenguaje de programación Go (también conocido como Golang) se ha convertido cada vez más popular. Es conocido por su simplicidad y rendimiento eficiente, similar a un lenguaje de bajo nivel como C++. Mientras se trabaja con una base de datos, la migración de esquema es una ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-realizar-migraciones-de-base-de-datos-usando-go-migrate/</link>
                <guid isPermaLink="false">664abddd26bf7b0404c5d846</guid>
                
                    <category>
                        <![CDATA[ go ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Golang ]]>
                    </category>
                
                    <category>
                        <![CDATA[ base de datos ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elias Ezequiel Pereyra Gomez ]]>
                </dc:creator>
                <pubDate>Wed, 29 May 2024 18:26:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2024/05/Blue-and-Pink-3D-Elements-Student-Part-Time-Graphic-Designer-Video-Resume-Talking-Presentation.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/database-migration-golang-migrate/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Perform Database Migrations using Go Migrate</a>
      </p><p>Desde su introducción, el lenguaje de programación Go (también conocido como Golang) se ha convertido cada vez más popular. Es conocido por su simplicidad y rendimiento eficiente, similar a un lenguaje de bajo nivel como C++.</p><p>Mientras se trabaja con una base de datos, la migración de esquema es una de las tareas más importantes que los desarrolladores hacen a lo largo del ciclo de vida del proyecto. En este artículo, te explicaré qué es una migración de base de datos y cómo hacerlo usando <a href="https://github.com/golang-migrate/migrate">go-migrate</a>.</p><h2 id="-qu-es-una-migraci-n-de-base-de-datos"><strong>¿Qué<strong> </strong>e<strong>s </strong>una Migración de Base de Datos<strong>?</strong></strong></h2><p>Una migración de base de datos, también conocido como una migración de esquema, es un conjunto de cambios que serán hechos a una estructura de objetos dentro de una base de datos relacional.</p><p>Es una forma de realizar e implementar cambios incrementales a la estructura de datos de una forma controlada y programática. Estos cambios son frecuentemente reversibles, lo que significa que se pueden deshacer o retrotraerse si se requiere.</p><p>El proceso de migración ayuda en cambiar el esquema de la base de datos desde su estado actual a un nuevo estado deseado, ya sea que implique agregar tablas y columnas, remover elementos, separar campos, o cambiar tipos y restricciones.</p><p>Al manejar estos cambios de una forma programática, se vuelve más fácil de mantener la consistencia y la precisión en la base de datos, así también como mantener un registro del historial de modificaciones que se le hizo.</p><h2 id="configuraci-n-e-instalaci-n"><strong>Configuración<strong> </strong>e<strong> </strong>Instalación</strong></h2><p><a href="https://github.com/golang-migrate/migrate">migrate</a> es una herramienta CLI que puedes usar para ejecutar migraciones. Puedes instalarlo fácilmente en varios sistemas operativos tales como Linux, Mac y Windows usando gestores de paquetes como curl, brew, y scoop, respectivamente.</p><p>Para más información en cómo instalar y usar la herramienta, puedes referirte a la documentación oficial.</p><p>Para instalar la herramienta CLI de <strong>migrate</strong> usando <a href="https://scoop.sh/">scoop</a> en Windows, puedes seguir estos pasos:</p><pre><code class="language-bash">$ scoop install migrate</code></pre><p>Para instalar la herramienta CLI de <strong>migrate</strong> usando <strong><a href="https://curl.se/">curl</a></strong> en Linux, puedes seguir estos pasos:</p><pre><code class="language-bash">$ curl -L https://packagecloud.io/golang-migrate/migrate/gpgkey| apt-key add -
$ echo "deb https://packagecloud.io/golang-migrate/migrate/ubuntu/ $(lsb_release -sc) main" &gt; /etc/apt/sources.list.d/migrate.list
$ apt-get update
$ apt-get install -y migrate</code></pre><p>Para instalar la herramienta CLI de <strong>migrate</strong> usando <a href="https://brew.sh/es/">brew</a> en Mac, puedes seguir estos pasos:</p><pre><code class="language-bash">$ brew install golang-migrate</code></pre><h2 id="c-mo-crear-una-nueva-migraci-n"><strong>Cómo crear<strong> </strong>una nueva migración</strong></h2><p>Crear un directorio como <code>database/migration</code> para almacenar todos los archivos de migración.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-263.png" class="kg-image" alt="image-263" width="600" height="400" loading="lazy"><figcaption>Estructura de archivos fuentes en el IDE GoLand</figcaption></figure><p>Luego, crea archivos de migración usando el siguiente comando:</p><pre><code class="language-bash">$ migrate create -ext sql -dir database/migration/ -seq init_mg</code></pre><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-267.png" class="kg-image" alt="image-267" width="600" height="400" loading="lazy"><figcaption>Salida de terminal mostrando mensaje de creación de migración exitoso</figcaption></figure><p>Usas <code>-seq</code> para generar una versión secuencial y <code>init_mg</code> es el nombre de la migración.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-269.png" class="kg-image" alt="image-269" width="600" height="400" loading="lazy"><figcaption>Estructura de archivos fuentes en el IDE GoLand</figcaption></figure><p>Una migración típicamente consiste de dos archivos distintos, uno para mover la base de datos a un nuevo estado (denominado como "up") y otro para revertir los cambios hechos al estado previo (denominado como "down").</p><p>El archivo "up" se usa para implementar los cambios deseados a la base de datos, mientras que el archivo "down" se usa para deshacer esos cambios y volver a la base de datos a su estado previo.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2023/01/Database-migration.jpg" class="kg-image" alt="Database-migration" width="600" height="400" loading="lazy"><figcaption>Flujo de migración de una base de datos</figcaption></figure><p>El formato de esos archivos para SQL son:</p><pre><code class="language-bash">{version}_{título}.down.sql
{version}_{título}.up.sql</code></pre><p>Cuando creas archivos de migración, estarán vacíos por defecto. Para implementar los cambios que quieres, necesitarás rellenarlos con las solicitudes SQL apropiadas.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-282.png" class="kg-image" alt="image-282" width="600" height="400" loading="lazy"><figcaption>Solicitudes SQL para migración de datos</figcaption></figure><h3 id="c-mo-ejecutar-la-migraci-n-up"><strong>Cómo<strong> </strong>ejecutar la<strong> </strong>Migración<strong> Up</strong></strong></h3><p>Para ejecutar sentencias de SQL en los archivos de migración, la migración requiere de una conexión válida a una base de datos Postgres.</p><p>Para lograr esto, necesitarás proveer una cadena de conexión en el formato apropiado.</p><pre><code class="language-bash">$ migrate -path database/migration/ -database "postgresql://username:secretkey@localhost:5432/database_name?sslmode=disable" -verbose up</code></pre><p>Ahora, en tu terminal de Postgres, puedes verificar las nuevas tablas creadas usando los siguientes comandos:</p><pre><code class="language-bash">\d+

\d+ nombre_tabla DESCRIBE TABLE</code></pre><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2023/01/image-286.png" class="kg-image" alt="image-286" width="600" height="400" loading="lazy"><figcaption>Mostrando datos de tabla en Postgres</figcaption></figure><h3 id="c-mo-retrotraer-migraciones"><strong>Cómo<strong> </strong>retrotraer<strong> </strong>migraciones</strong></h3><p>Si quieres revertir la migración, puedes hacerlo usando la siguiente etiquta <code>down</code>:</p><pre><code class="language-bash">$ migrate -path database/migration/ -database "postgresql://username:secretkey@localhost:5432/database_name?sslmode=disable" -verbose down</code></pre><p>Eliminará la columna <code>email</code> de ambas tablas como se menciona en el archivo <code>000002_init_mg.up.sql</code>.</p><p>Ahora, verifiquemos la base de datos y veamos si <code>email</code> ha sido eliminado o no:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2023/01/Screenshot_20230126_102731.png" class="kg-image" alt="Screenshot_20230126_102731" width="600" height="400" loading="lazy"><figcaption>Mostrando datos de tablas actualizados en Postgres</figcaption></figure><h3 id="c-mo-resolver-errores-de-migraci-n"><strong>Cómo resolver Errores de Migración</strong></h3><p>Si una migración contiene un error y se ejecuta, migrate evitará que cualquier migración se ejecute en la misma base de datos.</p><p>Un mensaje de error como <code>Dirty database version 1. Fix and force version</code> se mostrará, incluso después que se arregle el error de migración. Esto indica que la base de datos está "sucio" y necesita ser investigado.</p><p>Es necesario determinar si la migración fue aplicado parcialmente o no. Una vez que has determinado esto, la versión de la base de datos debería ser forzado a reflejar su estado verdadero usando el comando force.</p><pre><code class="language-bash">$ migrate -path database/migration/ -database "postgresql://username:secretkey@localhost:5432/database_name?sslmode=disable" force &lt;VERSION&gt;</code></pre><h3 id="c-mo-agregar-comandos-en-un-archivo-makefile"><strong>Cómo agregar<strong> </strong>comandos<strong> </strong>e<strong>n </strong>un archivo<strong> Makefile</strong></strong></h3><pre><code class="language-makefile">migration_up: migrate -path database/migration/ -database "postgresql://username:secretkey@localhost:5432/database_name?sslmode=disable" -verbose up

migration_down: migrate -path database/migration/ -database "postgresql://username:secretkey@localhost:5432/database_name?sslmode=disable" -verbose down

migration_fix: migrate -path database/migration/ -database "postgresql://username:secretkey@localhost:5432/database_name?sslmode=disable" force VERSION</code></pre><p>Ahora, puedes ejecutar <code>$ make migration_up</code> para 'up', <code>$ make migration_down</code> para 'down', y <code>$ make migration_fix</code> para arreglar el problema de migración.</p><p>Antes de ejecutar el makefile, asegúrate que el número correcto de la versión está incluido en el comando <code>migration_fix</code>.</p><h2 id="conclusi-n"><strong><strong>Conclusión</strong></strong></h2><p>Los sistemas de migración típicamente generan archivos que pueden ser compartidos entre desarrolladores y múltiples equipos. También pueden ser aplicados a múltiples bases de datos y mantenidos en control de versiones.</p><p>Mantener un registro de los cambios a la base de datos hace posible el poder rastrear el historial de modificaciones que se le hicieron. De esta forma, el esquema de la base de datos y el entendimiento de la aplicación de esa estructura pueden evolucionar juntos.</p><p>Eso concluye nuestra discusión en migración de base de datos. Espero que la información te haya resultado útil e informativo.</p><p>Si disfrutaste leer este artículo, por favor considera compartirlos con tus colegas y con tus amigos en las redes. Adicionalmente, por favor considera seguirme en <a href="https://twitter.com/RwiteshBera/">Twitter</a> para más actualizaciones sobre tecnología y programación. ¡Gracias por leer!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Explicación de genéricos en Go con ejemplos de código ]]>
                </title>
                <description>
                    <![CDATA[ Se propuso incluir genéricos en el lenguaje de programación Go hace unos años, y finalmente se aceptó la propuesta formal en el 2021. La versión de G0 1.18 en marzo de 2022 fue el que incluyó, por primera vez, soporte para genéricos [https://go.dev/blog/intro-generics]. Pero, ¿cómo se verá afectado Go por ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/explicacion-de-genericos-en-go-con-ejemplos-de-codigo/</link>
                <guid isPermaLink="false">6331a6ab36d7bd096041b691</guid>
                
                    <category>
                        <![CDATA[ go ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ian Cowley ]]>
                </dc:creator>
                <pubDate>Wed, 30 Nov 2022 16:45:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2022/09/6048ce09a7946308b7685b45.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artículo original:</strong> <a href="https://www.freecodecamp.org/news/generics-in-golang/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Generics in Go Explained with Code Examples</a>
      </p><p>Se propuso incluir genéricos en el lenguaje de programación Go hace unos años, y finalmente se aceptó la propuesta formal en el 2021. La versión de G0 1.18 en marzo de 2022 fue el que incluyó, por primera vez, <a href="https://go.dev/blog/intro-generics">soporte para genéricos</a>.</p><p>Pero, ¿cómo se verá afectado Go por los genéricos? ¿Cambiará nuestra manera de escribir el código?</p><p>Para poder responder a estas preguntas, tenemos que analizar detalladamente cómo funciona la programación genérica. Afortunadamente, el equipo de Go nos ha proporcionado un <a href="https://go2goplay.golang.org/">compilador de web</a> donde podemos experimentar con genéricos.</p><h2 id="pero-qu-es-lo-que-realmente-cambia-con-la-introducci-n-de-gen-ricos-en-go"><strong>Pero, ¿qué es lo que realmente cambia con la introducción de genéricos en Go?</strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-316.png" class="kg-image" alt="image-316" width="600" height="400" loading="lazy"><figcaption>Photo by <a href="https://unsplash.com/@anniespratt?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Annie Spratt</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Unsplash</a></figcaption></figure><p>Los genéricos permiten que nuestras funciones o estructuras de datos acepten varios tipos, que se definen en su forma genérica.</p><p>Para entender bien lo que significa esta frase, veamos un caso muy simple:</p><p>Imaginemos que tienes que hacer una función que tome un fragmento y la imprima. Así, podrías escribir este tipo de función:</p><pre><code class="language-go">func Print(s []string) {
	for _, v := range s {
		fmt.Print(v)
	}
}</code></pre><p>Sencillo, ¿verdad? Y, ¿qué pasaría si quisiéramos que ese fragmento sea un entero? Para esto, tendrías que crear un nuevo método: </p><pre><code>func Print(s []int) {
	for _, v := range s {
		fmt.Print(v)
	}
}</code></pre><p>Estas soluciones podrían parecer redundantes, ya que solo estamos cambiando el parámetro. Sin embargo, así es como lo solucionamos ahora mismo en Go sin tener que recurrir a convertirlo en alguna interfaz.</p><p>Ahora con los genéricos, nos permitirán declarar nuestras funciones de esta manera:</p><pre><code>func Print[T any](s []T) {
	for _, v := range s {
		fmt.Print(v)
	}
}</code></pre><p>En la función de arriba, estamos declarando dos cosas:</p><ol><li>Por un lado, tenemos <code>T</code>, que es el tipo de la palabra clave <code>any</code> (esta palabra clave se define específicamente como parte de un genérico, lo que indica cualquier tipo)</li><li>Y nuestro parámetro, donde tenemos la variable <code>s</code> cuyo tipo es una fragmento de <code>T</code>.</li></ol><p>Ahora podremos hacer una llamada a nuestro método de esta manera:</p><pre><code class="language-go">func main() {
	Print([]string{"Hello, ", "playground\n"})
	Print([]int{1,2,3})
}
</code></pre><p>Un método para cualquier tipo de variable: genial, ¿verdad?</p><p>Esta es solo una de las implementaciones muy básicas que hay para genéricos. Aun así, ya tiene buena pinta.</p><p>Exploremos un poco más y veamos hasta dónde nos pueden llevar los genéricos.</p><h2 id="limitaciones-de-los-gen-ricos"><strong>Limitaciones de los genéricos</strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-317.png" class="kg-image" alt="image-317" width="600" height="400" loading="lazy"><figcaption>Photo by <a href="https://unsplash.com/@nickeedoo?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Nick Tiemeyer</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Unsplash</a></figcaption></figure><p>Hemos visto lo que se puede hacer con los genéricos. Nos permiten especificar una función que puede aceptar cualquier tipo de parámetro.</p><p>Pero el ejemplo de antes era muy simple. Existen limitaciones al uso de los genéricos. Imprimir, por ejemplo, es bastante sencillo, ya que Go puede imprimir cualquier tipo de variable que se le agregue.</p><p>¿Pero qué pasa si queremos hacer algo más complejo? Vamos a imaginar que hemos definido nuestros propios métodos para una estructura y queremos hacer una llamada:</p><pre><code class="language-go">package main

import (
	"fmt"
)

type worker string

func (w worker) Work(){
	fmt.Printf("%s is working\n", w)
}


func DoWork[T any](things []T) {
    for _, v := range things {
        v.Work()
    }
}

func main() {
	var a,b,c worker
	a = "A"
	b = "B"
	c = "C"
	DoWork([]worker{a,b,c})	
}
</code></pre><p>Y esto devolvería lo siguiente:</p><pre><code>type checking failed for main
prog.go2:25:11: v.Work undefined (type bound for T has no method Work)</code></pre><p>No se ejecuta porque la fragmento procesada dentro de la función es de tipo <code>any</code> y no implementa el método <code>Work</code>, lo que hace que no se ejecute.</p><p>Podríamos hacer que funcionara usando una interfaz:</p><pre><code class="language-go">package main

import (
	"fmt"
)

type Person interface {
    Work()
}

type worker string

func (w worker) Work(){
	fmt.Printf("%s is working\n", w)
}

func DoWork[T Person](things []T) {
    for _, v := range things {
        v.Work()
    }
}

func main() {
	var a,b,c worker
	a = "A"
	b = "B"
	c = "C"
	DoWork([]worker{a,b,c})
}
</code></pre><p>Imprimiría lo siguiente:</p><pre><code>A is working
B is working
C is working</code></pre><p>Funcionaría bien con la interfaz, pero también lo haría con una interfaz sin el genérico:</p><pre><code class="language-go">package main

import (
	"fmt"
)

type Person interface {
    Work()
}

type worker string

func (w worker) Work(){
	fmt.Printf("%s is working\n", w)
}

func DoWorkInterface(things []Person) {
    for _, v := range things {
        v.Work()
    }
}

func main() {
	var d,e,f worker
	d = "D"
	e = "E"
	f = "F"
	DoWorkInterface([]Person{d,e,f})
}
</code></pre><p>Imprimiría lo siguiente:</p><pre><code>D is working
E is working
F is working</code></pre><p>El uso de los genéricos solo añade un extra de lógica a nuestro código. Cuando usar solo la interfaz sea suficiente, no habría ningún motivo para añadir genéricos al código.</p><p>Los genéricos aún se encuentran en sus primeras fases de desarrollo y todavía tienen límites a la hora de realizar procesamientos complejos.</p><h2 id="jugando-con-las-restricciones"><strong>Jugando con las restricciones</strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-318.png" class="kg-image" alt="image-318" width="600" height="400" loading="lazy"><figcaption>Photo by <a href="https://unsplash.com/@pbrandao?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Paulo Brandao</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Unsplash</a></figcaption></figure><p>Antes, usamos el tipo <code>any</code> para nuestra restricción genérica. Además de ese tipo, hay algunas otras restricciones que podemos usar.</p><p>Una de las restricciones es <code>comparable</code>. Vamos a ver cómo funciona:</p><pre><code class="language-go">func Equal[T comparable](a, b T) bool {
    return a == b
}

func main() {
	Equal("a","a")
}</code></pre><p>Aparte de eso, también podemos intentar crear nuestra propia restricción de la siguiente manera:</p><pre><code class="language-go">package main

import(
	"fmt"
)

type Number interface {
    type int, float64
}

func MultiplyTen[T Number](a T) T{
	return a*10
}

func main() {
	fmt.Println(MultiplyTen(10))
	fmt.Println(MultiplyTen(5.55))
}</code></pre><p>Y me parece bastante bueno: podemos tener una función para una expresión matemática simple. Por lo general, terminaremos haciendo dos funciones para incorporarlo o usaremos la reflexión, por lo que solo escribiremos una función.</p><p>Si bien todo esto es bastante interesante, aún tenemos que experimentar un poco para crear nuestras propias restricciones. Todavía es pronto para conocer todas las limitaciones de los genéricos. Y debemos tener cuidado de no abusar de ellos y usarlos solo si estamos realmente seguros de que sean necesarios.</p><h2 id="otras-formas-de-usar-los-gen-ricos"><strong>Otras formas de usar los genéricos</strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-319.png" class="kg-image" alt="image-319" width="600" height="400" loading="lazy"><figcaption>Photo by <a href="https://unsplash.com/@jotaemee?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Marcelo Franchi</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 17.6px; vertical-align: baseline; background-color: transparent; color: var(--gray90); text-decoration: underline; cursor: pointer; word-break: break-word;">Unsplash</a></figcaption></figure><p>Además de usar los genéricos como parte de una función, también puedes declararlos como variables de la siguiente manera:</p><pre><code>type GenericSlice[T any] []T</code></pre><p>Y puedes usar esto como un parámetro en una función o puedes crear un método de ese tipo:</p><pre><code class="language-go">func (g GenericSlice[T]) Print() {
	for _, v := range g {
		fmt.Println(v)
	}
}

func Print [T any](g GenericSlice[T]) {
	for _, v := range g {
		fmt.Println(v)
	}
}

func main() {
	g := GenericSlice[int]{1,2,3}
	
	g.Print() //1 2 3
	Print(g) //1 2 3
}</code></pre><p>El uso cambiaría según tus necesidades. Diría que todavía tenemos que experimentar más con genéricos para ver qué casos de uso funcionan mejor.</p><h2 id="mi-opini-n-sobre-los-gen-ricos">Mi opinión sobre los genéricos</h2><p>Los genéricos están todavía en sus fases iniciales, pero estoy bastante impresionado con la forma en la que se gestionan. No hace falta saber muchos términos complicados ni muchas librerías para implementar genéricos, y esta simplicidad es lo que hace que sean geniales.</p><p>Hay varios casos de uso en los que ya puedo intuir que usar genéricos será mejor, como por ejemplo en el caso con el método de multiplicación. Una cosa que a lo mejor confunde a la gente es que los genéricos podrían ser un sustituto para el uso de interfaces (tanto el tipo de interfaz{} como la implementación de la interfaz).</p><p>Mi consejo es no pensar en los genéricos como un sustituto de nada. Los genéricos son simplemente una herramienta más al alcance de los desarrolladores. Por otro lado, aunque los genéricos te parezcan elegantes y geniales, y quieras usarlos en cada bloque de tu código, te aconsejo que no los uses en exceso; úsalos cuando realmente los necesites y no los metas en todos los sitios en donde puedan encajar.</p><p>Eso es todo. Gracias por leer mi artículo, y espero sinceramente que los genéricos te puedan resultar útiles.</p><p>¡Qué disfrutéis de los genéricos!</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
