Héctor Álvarez

Taller tecnologías móviles

Introducción a Dart

Esquema de la clase

  • Introducción
  • Listas
  • Funciones y Clases
  • Constructores
  • Getters y Setters
  • Async

Introducción

Dart es un lenguaje de programación creado por Google en 2013 (lanzamiento oficial) con enfoque web (Dart a JavaScript) y ha evolucionado para suplir distintos tipos de desarrollo.

Tiene una sintaxis parecida a C, TypeScript.

Es un lenguaje de programación orientado a objetos con recolector de basura (Garbage collector) similar a Java/Kotlin.

Es utilizado para desarrollar múltiples tipos de aplicaciones (Web frontend y backend, aplicaciones de escritorio y móviles).

Utiliza el estándar ECMA-408 (la versión 1.0), pueden descargar las versiones actualizadas desde acá (https://dart.dev/guides/language/spec).

Características principales

AOT: Compilado a código máquina (nativo). Utilizado al momento de generar una aplicación en release (Flutter). Por lo que no hay pérdida de rendimiento al interpretarlo o ejecutarlo en una VM.

JIT: Compilado rápido para modo DEBUG y Hot Reload. Funciona de la misma manera que JavaScript, pero en DartVM en nuestro dispositivo de desarrollo (target).

Es un lenguaje tipado, aunque tiene tipos de datos dinámicos.

Características principales

Es fácil de aprender.


                            void main() {
                              for (int i = 0; i < 5; i++) {
                                print('hello ${i + 1}');
                              }
                            }
                        

Ver resumen del lenguaje

Primer programa en Dart

Utilizaremos Dartpad.dev para nuestros ejemplos: DartPad.

Cada programa necesita un método main, como punto de partida.

Primer programa en Dart

Dart provee información importante al momento de escribir nuestro código (warnings e info).

Primer programa en Dart

Elementos que componen un programa en Dart:

void: tipo de dato de retorno del método.

main(): función principal.

{…}: Inicio y cierre de bloque.

print(‘…’): función que imprime en pantalla.

//…: Comentario de línea.

/*…*/: Comentario de bloque.

Variables y concatenación de Strings

Las variables se declaran generalmente con un tipo de dato, en caso contrario Dart lo tomará como tipo de dato “dynamic”.

Variables y concatenación de Strings

Al especificar var o tipo_de_dato a una variable, estamos creando una variable (puede modificar su valor), en caso que queramos fijar datos estáticos o constantes debemos preceder con “const” o “final”.

Variables y concatenación de Strings

Podemos utilizar dos formas de concatenar string, utilizando el símbolo de adición (+) o utilizando el símbolo dollar ($).

Tipos de datos

Existen palabras reservadas para especificar tipos de datos, cada tipo de dato es tratado como un objeto (como en java), por lo que cada tipo de datos tiene sus propias métodos.

Condiciones

Dart nos permite realizar condiciones if, else, else if. Para ver más, revisar documentación (Branches).

Condiciones

También podemos utilizar el símbolo de negación (!) para negar una condición:
if(!heroe)…

Condiciones

En caso que queramos parar la ejecución del programa porque nos falta un dato o por un error, podemos utilizar la función throw.

Listas

Las listas son colecciones que tienen un dato en común.

Es un tipo de datos muy similar al arreglo en otros lenguajes.límites aunque se puede especificar el tamaño fijo.

La lista puede crecer indefinidamente, aunque se puede especificar un tamaño fijo.

Listas

En Dart la palabra reservada new es completamente opcional.

Listas

Dart nos provee múltiples formas para poder crear bucles y recorrer listas.

Mapas

Un Map es una variable/objeto que se compone de atributos llave/valor, también son conocidas como diccionario de datos.

Funciones

Hemos visto dos funciones, print y main. Las funciones o métodos nos permiten dividir el trabajo en pequeñas porciones reutilizables.

En Dart las funciones pueden retornar un tipo de valor asignado o ser vacías y simplemente trabajar sin devolver nada (void).

Las funciones pueden contener o no contener parámetros de entrada, pueden tener parámetros simples y pueden tener parámetros con nombre.

Los parámetros de entrada pueden ser obligatorios (requeridos) u opcionales (con valores por defecto preestablecidos).

Las funciones pueden ser públicas o privadas (los elementos privados son precedidos por un guión bajo: _ ).

Las funciones se escriben en minúscula y en estilo camelCase.

Funciones

Funciones

Es necesario utilizar la palabra required para especificar que un atributo es requerido siempre y forzar su inicialicación (No Nulo).

Funciones

Podemos crear parámetros con datos predefinidos: String msg = ''

Funciones

Existen parámetros (y variables posiblemente nulas) String? msg, y se reconocen por el símbolo de interrogación (?) al final del tipo de variable.

Clases

El uso de clases en Flutter es de suma importancia, ya que lo utilizaremos tanto al invocar elementos gráficos (Widgets) como en la lógica misma de nuestro desarrollo.

Cada clase comienza con Mayúscula utilizando el estilo UpperCamelCase o PascalCase.

Dentro de la clase podremos agregar sus propiedades/atributos y métodos.

Podemos tener un constructor y constructores con nombre.

No tenemos sobrecarga de constructores.

Clases

Clases

El constructor, a su vez, puede recibir parámetros con nombre y obligatorios.

Podemos incluso agregar parámetros con valores por defecto.

También es posible recibir los parámetros apuntando directamente a los atributos, lo que nos permitirá reducir el tamaño del constructor.

Clases

Clases

Clases

Constructores nombrados

Al no poseer sobrecarga de constructores no podremos redefinir un constructor con otros parámetros de entrada.

Para poder inicializar nuestra clase sin sobrecarga de constructores, es necesario utilizar los constructores con nombre.

Clases

Getters y Setters

Los Getters y Setters nos permiten interactuar con componentes privados de la clase.

El Setter ese comporta como una función de retorno vacío en el cual podemos especificar el parámetro de entrada.

El getter nos permite retornar un valor dependiendo del tipo de dato que este sea.

Desde fuera de la clase, interactuaremos con los Getters y Setters de forma natural, como si fuesen atributos.

Dart verificará si queremos ingresar u obtener datos para usar uno u otro.

Getters y Setters

Clases Abstractas

Una clase abstracta no se puede instanciar o crear como un objeto (new Class()), sino que permite agregar funcionalidad a una clase “hija” mediante la implementación, extensión o mixin.

La implementación, nos permite generar esquemas o esqueletos de clase que fuercen la completa re-implementación de la clase abstracta que definimos (interfaz).

La extensión de clase, se comporta al igual que en Java, permitiéndonos heredar propiedades y métodos de una clase padre a una clase hija (desde donde la invocamos).

Clases Abstractas

Podemos utilizar la herencia con las clases abstractas de la misma forma que una clase normal, utilizamos la palabra clave extends para heredar de una clase padre.

Clases Abstractas

Una implementación es útil para crear una clase base sobre la cual trabajar, dando una estructura que podemos usar en clases similares a modo de esqueleto.

Mixins

Los Mixins nos permiten asignar funcionalidades de distintas clases abstractas a una clase que nosotros definamos, independiente de la jerarquía de las clases.

Es útil cuando necesitamos que una clase tenga comportamientos muy distintos pero que se complementan de alguna manera sin la necedidad de crear una bola de nieve de Herencias.

Mixins

Futuros

Los futuros o promesas son muy importantes al momento de crear funciones asíncronas, como por ejemplo al momento de realizar una acción que necesite una espera prolongada.

Los futuros crean un hilo/proceso aparte de nuestro programa principal, por lo que nuestro programa queda libre de hacer cualquier cosa durante ese periodo de tiempo y no queda “congelado” a la espera de una respuesta.

Cuando un futuro se completa retorna el valor (o lo que sea que esté haciendo) al hilo principal.

Futuros

Futuros: Async/Await

Nos permite esperar a un futuro para que el proceso de nuestra aplicación se ejecute ordenadamente de forma secuencial (sacrificando la velocidad por la precisión de nuestro algoritmo).

Los constructores de una clase no pueden ser asíncronos.

El método que necesite esperar una llamada asíncrona se ejecutará completamente en un hilo secundario.

Futuros: Async/Await