Null safety y la asignación tardía en español

Daniel Herrera Sánchez
5 min readJun 7, 2021

Con la salida de Flutter 2x muchos quedamos con la curiosidad de saber que era null safety y la asignación tardía de variables, a su vez también nos generaba intriga saber por que esto optimiza los tamaños de los binarios. Si deseas saber en mas detalle estos temas te animo a que me acompañes en este artículo donde explicaremos estos puntos.

Null Safety te protege no te limita

Para entender una herramienta, hay que primero comprender que problema soluciona. Pensemos que tenemos el siguiente código en Flutter 1x:

Como vemos la función isEmpty valida si un String tiene contenido o no. Supongamos que la entrada a isEmpty proviene de un servicio y por error se nos olvidó validar que el contenido no fuera nulo … ¿Qué pasaría?

Esto originaría un crash en la aplicación, que solo sería visible en producción. Esto es terrible pues nosotros queremos ser avisados desde el momento de compilación de los posibles errores. Por eso Null Safety llegó a ayudarnos.

Supongamos que vamos a crear una variables edad y la vamos a mostrar en pantalla en Flutter 1x :

Si por error, se nos olvidó hacer una asignación de valor a la variable edad, en consola nos mostraba un null. Esto indica que si utilizáramos la variable edad para algún procesamiento numérico podríamos tener un error pese a que supuestamente el archivo había compilado bien.

Ahora miremos que arroja la consola con el mismo código pero en Flutter 2x:

Desde el momento de edición el Dart Analyzer nos dice que la variable edad debe ser asignada antes de ser utilizada, es decir que ahora desde tiempo de desarrollo nos están protegiendo de que vengan parámetros nulos.

Pero … ¿Cómo hago si deseo y soy consciente de que una variable puede ser nula? ¿Cómo hago para no tener que asignar un valor tan pronto se crea mi variable?

lo único que necesitamos es agregar el signo de interrogación en la definición de la variable, así como se muestra a continuación :

Esto devolverá en consola nuevamente un null. Pero ¿Cómo funciona esto ?

Miremos la estructura de objetos y subtipos en Flutter 1x :

En este caso vemos que null es un subtipo de todas los objetos definidos. Esto significa que todos los objetos podían llegar a ser nulos. Pero, ahora en 2x el diagrama se ve así :

Esto nos indica de que en ningún momento null será un subtipo de los objetos de Flutter. Se puede considerar que los elementos con signo de interrogación son un nuevo tipo de objeto que admiten nulos (nulleable).

Teniendo esto claro solo nos queda decir que volver nuestros objetos “Nullables” no es la mejor estrategia. Es como si nos hubieran dado un chaleco salvavidas y nos lo quitáramos por que confiáramos en que somos excelentes nadadores, pero en el basto mar de una solución digital necesitamos estar protegidos. Es mejor solo utilizar el signo de interrogación en casos que seamos 100% conscientes de las implicaciones y no salir a producción con elementos no mapeados (por ejemplo, escenarios donde pueda llegar a valer nulo).

Pero … ¿Qué pasa si necesito crear una variable y asignar más tarde su valor?

Asignación tardía … una herramienta poderosa

La asignación tardía viene a salvarnos en escenarios donde definamos un objeto pero asignemos su valor más adelante. También ayuda a optimizar el manejo de la memoria RAM en nuestras aplicaciones pues ¿Porqué asignas un espacio en memoria que aún no vas a utilizar?

En Flutter 1x el siguiente código corría sin problemas :

Pero en 2x fallará sin lugar a dudas … ¿Por qué?

La variable _sabor es creada tan pronto se crea una instancia de la clase Malteada, entonces Null Safety detectará el riesgo de que se utilice la misma sin haberla asignado.

¿Cómo solucionamos esto?

Bueno podemos decirle a Flutter que esta variable será asignada en un futuro.

Esto lo hacemos utilizando el marcador late. De la siguiente forma :

Al ejecutar este código en Flutter 2x no se generará ningún error pues el marcador late hará que solo cuando se ejecute chocolate ( ) o vainilla ( ) se cree la variable y a su vez sea asignado un valor para la misma😲.

Ahora, ¿Te acuerdas que todo final debía ser inicializado? utilizando el marcador late ya no es necesario, sencillamente podemos crearlo así :

late final String _sabor;

¿Por qué optimiza la memoria Null Safety?

Al convertir el binario se debían hacer unas validaciones adicionales para determinar si un objeto podía llegar a ser nulo o no. Con Null Safety por defecto sabemos que el objeto vendrá no nulo a no ser que el desarrollador indique lo contrario y en ese caso tampoco requeriría de validaciones adicionales. Eliminando una lógica asociada a todo este mapeo los binarios finales pueden hacer su trabajo más eficientemente y no crear escenarios que ya dejaron de ser relevantes.

Conclusiones

  • Null Safety llego para salvarnos, por eso debemos meditar muy bien donde colocaremos el dichoso símbolo de interrogación.
  • La asignación tardía de variables permite optimizar espacio en memoria y solo crear y asignar la variable cuando sea necesaria.
  • Deberíamos darle like a este artículo 😀 (o tal vez no?).

Bueno hemos llegado al final, espero que les haya gustado la información … si tienen alguna observación o inquietud no duden ponerlo en la caja de comentarios. Si el articulo te gustó por favor dale +50 👏👏🎉 🎉aplausos que eso contribuirá a sacar nuevos artículos mas adelante. Un abrazo grande a todos.

--

--

Daniel Herrera Sánchez

Flutter,Dart@GoogleDevExpert💙 • 🔴Youtube Channel Weincode •👨🏻‍💻FlutterMedellin Community Lead • 🙅🏻‍♂️Angular Content creator • Speaker •GitHub: weincoder