latest

Introducción al lenguaje Dart. Básico. Parte 2

Tras hablar un poco de Dart en la parte 1 de la introducción básica al lenguaje, aquí nos centraremos en otros apartados básicos de Dart. Debo remarcar que está introducción esta destinada a personas que ya conocen otros lenguajes de Programación Orientada a Objetos (POO), como Java o C# y, por lo tanto, no se explican conceptos muy básicos como, por ejemplo, qué es una variable o una constante. En resumen, "vamos directos al grano".

Método main(), declaración de variables y constantes

void main() {
     // Declaración (NO fuertemente tipada)
     var numSolicitudes = 32;
     print("Numero de solicitudes: ${numSolicitudes}");
}

Como podéis comprobar la declaración de variables requiere la palabra clave var. En este caso hemos aunado declaración y asignación de valor para la variable numSolicitudes. Observad que las sentencias acaban con ";" y el formato de la sintaxis usada en print para imprimir por pantalla el valor de la variable. Podéis probar el código vosotros mismos en DartPad.

También podemos hacer la declaración de variables de modo que Dart sea un Lenguaje Fuertemente Tipado indicando en la declaración el tipo de datos que almacenará dicha variable.

void main() {
     // var numSolicitudes = 32;
     // Declaración fuertemente tipada
     int numSolicitudes = 32;
     print("Numero de solicitudes: ${numSolicitudes}");
}

En el caso de la declaración y asignación de valora a constantes (una sola vez) hay que usar la palabra clave final.

void main() {
     // var numSolicitudes = 32;
     // Declaración fuertemente tipada
     int numSolicitudes = 32;
     // Declaración y asignación de constante
     final double notaCorteMin = 5.50;
     print("Numero de solicitudes: ${numSolicitudes} y" + 
         " Nota Corte Min: ${notaCorteMin}");
}

Tipos de datos básicos integrados en Dart (built-in types)

Dart maneja los tipos de datos básicos que incorpora como objetos, por tanto, tienen el valor null por defecto. Los tipos de datos básicos son los siguientes:

  • Números (num con los subtipos: int y double)
  • Cadenas (String)
  • Booleanos (bool)
  • Arrays (List)
  • Diccionarios (Map)

Si ejecutamos el siguiente fragmento de código desde DartPad podemos comprobar que al no haber asignado valor a las variables convocatoriaAbierta y anyoConvocatoria tienen el valor null por defecto.

void main() {
     // var numSolicitudes = 32;
     // Declaración fuertemente tipada
     int numSolicitudes = 32;
     // Declaración y asignación de constante
     final double notaCorteMin = 5.50;
     // Variables a null
     bool convocatoriaAbierta;
     var anyoConvocatoria;
  
     print("Numero de solicitudes: ${numSolicitudes} y" + 
         " Nota Corte Min: ${notaCorteMin}" +
         " ¿Está la convocatoria del año $anyoConvocatoria" + 
         " abierta? $convocatoriaAbierta");
}

Para los literales de String podemos usar indistintamente comillas simples o dobles. Dart entiende una cadena como una secuencia de caracteres Unicode codificados con UTF-16 (codificación son símbolos de longitud variable).

Podemos concatenar cadena de varias formas. Bien usando el operador "+" o mediante cadenas adyacentes (incluso con un salto de línea de por medio).

void main() {
  var s1 = 'La concatenación ' 'de cadenas'
    " funciona incluso con saltos de líneas.";
  assert(s1 == 'La concatenación de cadenas funciona incluso con '
    'saltos de líneas.');
	
  String s2 = 'El operador + ' + 'también funciona.';
  assert(s2 == 'El operador + también funciona.');
}

El operador "==" compara dos cadenas devolviendo true si albergan el mismo contenido, en términos de caracteres. Por su parte, la llamada a assert() es ignorada cuando la aplicación pasa a modo producción. Durante el desarrollo, assert(condicion) lanza una excepción salvo si dicha condición es true.  Usando la triple comilla simple (o triple comilla doble) podemos crear Strings multilínea, respetando su indentación, como en el siguiente ejemplo.

void main() {
  String s3 = """Esto es un ejemplo 
  de cadena 
       de múltiples líneas.""";
  print(s3); 
}

Con total seguridad los arrays, grupos ordenados de elementos, son el tipo de colección más usado en prácticamente la mayoría de lenguajes. En Dart, los arrays son objetos de tipo List, por lo que se suele usar el término "lista" para hacer referencia a ellos. Aquí tenéis un ejemplo sencillo de creación de listas en Dart:

void main() {
  var listaEnteros = [1,2,3];
  var listaCadenas = ["Uno","Dos","Tres","Cuatro"];
  
  for (int i=0; i <listaEnteros.length; i++){
    print(listaEnteros[i]);
  }
  for (int i=0; i <listaCadenas.length; i++){
    print(listaCadenas[i]);
  }
  // Una sentencia como la siguiente daría error: listaCadenas[0]=1;
}

En los dos casos, los elementos de la lista deben ser del mismo tipo de objeto. Por eso, si intentamos modificar un elemento de la listaCadenas, que internamente el analizador trata como List<String> y asignarle, por ejemplo, un número entero se produce un error durante la compilación. Como ocurre en otros lenguajes, e.j., Java, la indexación en las listas es de tipo zero-based, siendo el 0 el índice del primer elemento y list.length-1 el último.

Para crear una lista inmutable (que no se pueda modificar) en tiempo de compilación usamos la palabra clave const.

void main() {
  final listaCadenas = const ["Uno","Dos","Tres","Cuatro"];

  for (int i=0; i < listaCadenas.length; i++){
    print(listaCadenas[i]);
  }
  
  // Una sentencia como la siguiente lanzaría una excepción:
  // listaCadenas[0]="cero";
}

Los diccionarios (Map) son objetos que asocian claves y valores. Tanto las claves, como los valores pueden ser cualquier tipo de objeto. Además. cada clave sólo ocurre una vez, sin embargo, un valor puede usarse múltiples veces a lo largo de la estructura de tipo Map. El siguiente ejemplo de código lo constituyen dos mapas en Dart creados a partir de literales de diferente tipo.

void main() {
  var podiumFormato1 = {
      // clave: valor
      '1º': 'F. Albuquerque',
      '2º': 'S. Middleton',
      '3º': 'C. Braun' // la última "," del Map es opcional
  }; 
  var podiumFormato2 = {
      1: 'F. Albuquerque',
      2: 'S. Middleton',
      3: 'C. Braun',
  };
  print ("2º puesto en el formato1: ${podiumFormato1['2º']}" 
          "\n2º puesto en el formato2: ${podiumFormato2[2]}");
}

El analizador de Dart determina que podiumFormato1 es de tipo Map<String,String> y podiumFormato2 es de tipo Map<int,String>. De modo que si añadimos un tipo incorrecto (en la clave o en el valor) en cualquiera de los dos mapas el analizador lanzará un error.

También podemos construir los mapas del ejemplo anterior usando el constructor Map() como se muestra a continuación.

void main() {
  var podiumFormato1 = Map();
  podiumFormato1["1º"] = 'F. Albuquerque';
  podiumFormato1["2º"] = 'S. Middleton';
  podiumFormato1['3º'] = 'C. Braun';
    
  var podiumFormato2 = new Map();
  podiumFormato2[1]="F. Albuquerque";
  podiumFormato2[2]='S. Middleton';
  podiumFormato2[3]='C. Braun';
  
  print ("2º puesto en el formato1: ${podiumFormato1['2º']}" 
        "\n2º puesto en el formato2: ${podiumFormato2[2]}");
}

Como podéis comprobar en el primer caso no se ha utilizado la palabra clave new , previa al constructor, en la instanciación del objeto Map. Desde Dart 2, new es opcional. También podéis ver en el ejemplo anterior la manera de acceder a un valor de un Map a partir de una de sus claves (nombreMap[literalClave]). A diferencia de los arrays con List, si se accede a un índice (clave en este caso) que no está definido en la colección no se obtiene un error en tiempo de ejecución,  en su lugar, se retorna null.

Como en las listas/arreglos podemos usar .length para obtener el número de pares clave-valor del mapa. También podemos crear mapas inmutables/constantes en tiempo de compilación con la palabra clave const.

void main() {
  final podiumFormato1 = const {
      2: 'helio',
      10: 'neon',
      18: 'argon',
  };
  // Una sentencia como podiumFormato1[2]='oxígeno' 
  // lanzaría una excepción.
}

Seguiremos aprendiendo más sobre estructuras de datos y colecciones como List y Map a lo largo de este curso de Flutter. Os animamos a continuar con la parte 3 de la Introducción básica al lenguaje Dart.

Author image
Iván González is postdoctoral researcher at the Castilla-La Mancha University.
Ciudad Real (Spain)