Explicación de defer en Go

Publicado por parzibyte en

Explicación y ventajas de defer en Go

En este post se explica cómo usar defer en Go, así como sus ventajas e importancia.

El lenguaje de programación Go provee una característica muy especial y útil a la vez: defer. Esta sentencia ayuda mucho a la hora de programar con Go, pues permite ejecutar alguna sentencia al finalizar o terminar el flujo de una función, sin importar en qué punto se regrese.

Explicación y ventajas de defer en Go

Explicación y ventajas de defer en Go

Al principio suena complicada, pero su uso es realmente sencillo y no estamos obligados a usarlo si no queremos. De hecho se podría decir que es azúcar sintáctica del lenguaje.

Sentencia defer en Go

Esta sentencia ejecuta el código que le indicamos antes de que se termine la función, sin importar en qué punto se termine la misma. Un ejemplo básico es el siguiente (tomado de aquí):

Ese código imprimirá:

Hola

Mundo

En la primera línea se pone a defer fmt.Println("Mundo") y en la segunda fmt.Println("Hola"). Aunque parece que se imprimirá Hola y luego Mundo, el resultado es lo contrario.

Dicho de otra manera, el código de arriba es lo equivalente a escribir esto:

La sentencia defer en Go mueve el código al final de la función, si se quiere ver así, aunque en realidad lo ejecuta antes de que la función se termine, sin importar el punto en donde se hace el return.

Otro ejemplo de defer en Go

Veamos este programa que si bien no tiene mucho sentido, ejemplifica el uso de defer. Ya lo dije, defer permite que se ejecute código al terminar la función, sin importar en qué punto se termine.

Leemos a través del teclado la edad del usuario, si su edad es menor a 18, le indicamos que no puede ver el contenido y terminamos el flujo de la función con return.

En caso de que tenga más de 18 años, le mostramos un mensaje secreto.

Lo que quiero resaltar aquí, es que sin importar lo que el usuario escriba, al final se muestra el mensaje que dice que vuelva pronto. No importa si la función termina normalmente o “se interrumpe”, todo lo que esté agendado con defer se ejecutará antes de que la función se termine.

El código expuesto puede probarse aquí:

Equivalente en otros lenguajes

La sentencia defer en Go es un poco parecida a la sentencia finally de un try/catch que otros lenguajes de programación tienen; con la gran diferencia de que en Go no hay excepciones, pero esa es otra historia.

Recordemos que finally se ejecuta sin importar si se cae dentro del catch.

Ventajas de defer en Go

Vamos a analizar las ventajas que tiene defer en Go, porque esta sentencia, que yo sepa, no existe en los lenguajes de programación más populares.

Permite tener un código más legible

Cuando usamos defer, podemos terminar algo que estamos iniciando, pocas líneas después de lo primero. Por ejemplo, tomemos el ejemplo real en donde conectamos a Go con MySQL. Un fragmento de código para abrir la base de datos dice así:

Como ya abrimos la base de datos, indicamos que antes de salir de la función actual, la misma se cierre con db.Close(). No importa si abajo hay 10 millones de líneas, la base de datos se cerrará cuando se termine.

En un futuro cuando nosotros u otro programador lea el código, sabrá que la base de datos que se está abriendo, se está cerrando al final; sin importar en dónde.

Además, si más abajo hay múltiples condiciones que terminan la función, no tenemos que ir dentro de cada una de ellas y poner db.Close() en caso de que la función no siga su flujo normal.

Evita olvidar cerrar archivos, bases de datos, etcétera

El mismo ejemplo de arriba. Si hubiera muchas líneas de código y no existiera defer, a menudo olvidaríamos terminar lo que empezamos.

El ejemplo fue con una base de datos, pero lo mismo pasa con un archivo y cualquier otra cosa que se deba terminar cada que se empieza.

Más cosas de defer

Solamente queda mencionar que se puede llamar a defer las veces que sea necesario. Cuando eso pase, las sentencias se ejecutan en el orden inverso de como fueron llamadas.

Un ejemplo sencillo es el siguiente, en donde imprimimos 4 mensajes, 3 de ellos con defer. Al final, los mensajes se imprimirán ordenados.

Esto es porque la primera llamada a defer se ejecuta al final, la segunda antes del final, y así sucesivamente. El orden es LIFO: último en entrar, primero en salir.

El código de ejemplo se puede probar aquí:

Así es como funciona defer en Go.


parzibyte

He trabajado por más de 4 años en el desarrollo de software con experiencia en Java, PHP, JavaScript, HTML, Node.JS, Python, Android y Go. También he trabajado con bases de datos SQL como MySQL y SQLite, así como con bases de datos NoSQL usando MongoDB.Soy bueno utilizando algunos frameworks y herramientas como Firebase, jQuery, AngularJS, VueJS, CodeIgniter, Laravel, BulmaCSS, Bootstrap y Electron.Otros términos que conozco son: Arduino, GraphQL, API's, REST, AJAX, PouchDB, CouchDB, Experiencia de usuario, buenas prácticas de programación, Webpack, NPM, Administración de servidores y programación de scriptsLa plataforma en la que tengo más experiencia es la web, pero en mis ratos libres realizo unos pequeños ejercicios en C# y C.Estoy aquí para ayudarte a resolver tus problemas de programación y depuración :-)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

A %d blogueros les gusta esto: