diegoRodicio

Está documentación está a túa disposición sin ningún custo económico. Sen embargo, para a súa elaboración dedico moito tempo e recursos, polo que agradecería unha colaboración co que consideres oportuno. Gracias.

View Categories

🧠 Saber mais

Contido:

O sistema de tipos en Dart #

Dart é unha linguaxe con tipado estático e seguro (sound typing), o que significa que tenta garantir que os valores sempre coincidan co tipo declarado, tanto en tempo de compilación como en tempo de execución.

✅ Que significa “tipado seguro” (sound typing)? #

  • Erro en tempo de compilación se usas tipos incorrectos (ex: asignar un String a un int).
  • Erro en tempo de execución se un cast explícito falla (ex: object as String e non é un String).
  • Tipos obrigatorios pero non ten que ser sempre explícitos, xa que Dart pode inferir tipos automaticamente.

📍 Exemplo: Erro por inferencia incorrecta #

void printInts(List<int> a) => print(a);

void main() {
  var lista = [];
  lista.add(1);
  lista.add('2'); // ❌ engadimos un String

  printInts(lista); // Erro: List<dynamic> non é List<int>
}

✅ Solución: indicar o tipo da lista ao inicializala:

void main() {
  var lista = <int>[];
  lista.add(1);
  lista.add(2);
  printInts(lista); // Correcto
}

🛠 Boas prácticas e regras útiles #

🧪 Retornos e parámetros con tipos correctos #

  • Ao sobrescribir métodos, o tipo de retorno pode ser un subtipo.
  • Os parámetros non se poden restrinxir máis, só ampliar ou manter.
class Animal {
  Animal get parent => Animal();
  void chase(Animal a) {}
}

class Gato extends Animal {
  @override
  Gato get parent => Gato(); // ✅ retorno máis específico

  @override
  void chase(Object a) {} // ✅ parámetro máis xeral
}

🔥 Erros en tempo de execución por cast incorrecto #

int asumeString(dynamic obxecto) {
  String texto = obxecto; // ❌ pode fallar se non é String
  return texto.length;
}

void main() {
  print(asumeString(1)); // TypeError en tempo de execución
}

📌 Conclusión #

O sistema de tipos en Dart axuda a detectar erros antes de que sucedan, escribir código máis seguro e aproveitar mellor o compilador.

🔎 Máis información #

Non incluín toda a información sobre este punto, xa que excede os contidos que precisamos para o módulo de PMDM.

Se queres afondar máis, podes consultar a documentación oficial de Dart sobre o sistema de tipos:

👉 https://dart.dev/language/type-system

🧠 Patróns en Dart (Pattern Matching e Desestruturación) #

🔒 Os patróns en Dart están dispoñibles a partir da versión 3.0 do idioma.

Os patróns permiten comprobar e extraer valores dunha estrutura de datos de forma clara e concisa. A esta técnica tamén se lle chama desestruturación (destructuring).

📌 Para que serven os patróns? #

  • Saber se un valor ten unha certa forma (por exemplo: é unha lista? un mapa? ten 2 elementos?).
  • Ver se un valor coincide cunha constante.
  • Extraer datos de estruturas compostas como listas, mapas, rexistros ou obxectos.
  • Declarar variables a partir dos valores extraídos.

📍 Onde se poden usar patróns? #

  • Declaracións de variables: var (a, b) = (1, 2);
  • Asignacións: (x, y) = (y, x);
  • Condicións con switch ou if-case
  • Bucles for e for-in

✅ Exemplos básicos #

🟨 Desestruturación de tuplas (records) #

void main() {
  var (nome, idade) = ('Diego', 44);
  print('$nome ten $idade anos'); // Diego ten 44 anos
}

🔄 Intercambiar variables sen variable temporal #

void main() {
  var a = 'esquerda';
  var b = 'dereita';

  (a, b) = (b, a);

  print('$a - $b'); // dereita - esquerda
}

📋 Patróns en listas #

void main() {
  var lista = [1, 2, 3];
  var [a, b, c] = lista;

  print(a + b + c); // 6
}

🗺️ Patróns en mapas #

void main() {
  var datos = {'usuario': ['Lúa', 15]};

  switch (datos) {
    case {'usuario': [String nome, int idade]}:
      print('Usuario $nome ten $idade anos');
      break;
    default:
      print('Datos non válidos');
  }
}

🧪 Uso en switch para comprobar tipos ou valores #

void main() {
  var valor = 3;

  switch (valor) {
    case 1:
      print('Un');
    case >= 2 && <= 4:
      print('Entre dous e catro');
    default:
      print('Outro número');
  }
}

🔄 Uso en bucles for-in con mapas #

void main() {
  var hist = {'a': 10, 'b': 5};

  for (var MapEntry(:key, :value) in hist.entries) {
    print('$key apareceu $value veces');
  }
}

🧠 Conclusión #

Os patróns fan que o código sexa máis conciso, expresivo e seguro, especialmente cando traballamos con estruturas complexas ou precisamos validar datos. Son unha ferramenta moi potente, pero recomendada para alumnado cun certo dominio previo de Dart.

🧪 CodeLab #

Un CodeLab é un tutorial práctico e guiado que che permite aprender un concepto mentres escribes e executas código real paso a paso.

Se queres practicar o uso de patróns e desestruturación en Dart, podes seguir este codelab oficial:

👉 https://codelabs.developers.google.com/codelabs/dart-patterns-records

🔎 Máis información #

Non incluín toda a información sobre este punto, xa que excede os contidos que precisamos para o módulo de PMDM.

Se queres afondar máis, podes consultar a documentación oficial de Dart sobre os patróns na documentación oficial de Dart:
👉 https://dart.dev/language/patterns

🏷️ Metadata en Dart #

En Dart, a metadata permite engadir información adicional ao teu código usando anotacións.
Unha anotación comeza co símbolo @ seguido do nome dunha constante de tempo de compilación ou dun constructor constante.

🔹 Anotacións dispoñibles por defecto #

Dart inclúe algunhas anotacións que podes usar en calquera código:

AnotaciónUso principal
@DeprecatedMarca algo como obsoleto e permite engadir unha mensaxe.
@deprecatedVersión sen mensaxe (non recomendada).
@overrideIndica que se está sobrescribindo un método herdado.
@pragmaInformación especial para o compilador (uso avanzado).

🔹 Exemplo co uso de @Deprecated #

class Television {
  /// Usa [turnOn] no seu lugar.
  @Deprecated('Usa turnOn no canto deste método')
  void activate() {
    turnOn();
  }

  void turnOn() {
    print('Televisor acendido');
  }
}

🔍 @Deprecated inclúe unha mensaxe explicativa.
Tamén podes usar @deprecated sen mensaxe, pero non se recomenda.

🔹 Crear anotacións personalizadas #

Podes definir as túas propias anotacións creando unha clase const.
Por exemplo, imos crear unha anotación @Todo:

class Todo {
  final String quen;
  final String que;

  const Todo(this.quen, this.que);
}

E así é como se usa:

@Todo('Dash', 'Implementar esta función')
void facerAlgo() {
  print('Facendo algo...');
}

📌 Onde se pode usar metadata #

As anotacións poden colocarse antes de:

  • clases, funcións, métodos, construtores, parámetros, variables
  • importacións/exportacións
  • typedefs, campos ou tipos xenéricos

📚 Para saber máis #

🔗 Documentación oficial de Metadata en Dart →

📦 Librarías e importacións en Dart #

Dart permite organizar o código en librarías para facelo máis modular, reutilizable e privado.
Cada arquivo Dart é unha libraría, mesmo se non inclúe a directiva library.

🔹 Librarías e privacidade #

As librarías en Dart tamén son unha unidade de privacidade:
os identificadores que comezan por guión baixo _ só son accesibles desde dentro da mesma libraría.

🔍 Dart non usa public, private ou protected como outras linguaxes, senón que controla o acceso a través do uso de _ e da organización en librarías.

🔹 Importar librarías #

Usamos import para facer accesibles elementos doutro arquivo ou paquete.

import 'dart:math';               // Libraría estándar
import 'package:test/test.dart'; // Libraría dun paquete externo
import 'lib/utilidades.dart';    // Arquivo local

  • dart: → librarías propias de Dart (core SDK).
  • package: → paquetes externos xestionados con pub.
  • rutas relativas → arquivos locais do proxecto.

🔹 Prefixos para evitar conflitos #

Se importas dúas librarías que teñen o mesmo identificador, podes usar prefixos:

import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

Element e1 = Element();        // da lib1
lib2.Element e2 = lib2.Element(); // da lib2

🔹 Importacións selectivas #

Podes importar só partes dunha libraría ou excluír nomes concretos:

import 'package:lib1/lib1.dart' show foo;  // Só importa 'foo'
import 'package:lib2/lib2.dart' hide foo;  // Importa todo excepto 'foo'

📚 Principais librarías estándar de Dart #

LibraríaDescrición
dart:coreInclúe tipos e funcións básicos (String, int, etc.)
dart:mathFuncións matemáticas e constantes
dart:ioEntrada/saída para scripts ou apps de consola
dart:convertConversión de datos (JSON, UTF-8, Base64…)
dart:asyncFutures, Streams e programación asíncrona
dart:collectionEstruturas de datos avanzadas (Mapas, Set, etc.)
dart:js_interopInteroperabilidade con JavaScript en apps web

🔗 Máis información #

Para aprender máis sobre librarías, import, paquetes e xestión de código en Dart:

🚫 Sound null safety #

Dart incorpora un sistema chamado sound null safety, que evita erros comúns provocados polo uso de valores nulos de forma inesperada.

🔹 Que é null safety? #

O null safety axuda a previr erros que ocorren cando se accede a variables que conteñen null, pero que non deberían.

Con null safety:

  • Todas as variables deben inicializarse cun valor non nulo por defecto.
  • Unha variable non pode conter null, agás que o tipo se defina explicitamente como nullable.

🔗 Para saber máis #

📚 Librarías principais do núcleo de Dart #

Dart conta cun conxunto rico de librarías principais (core libraries) que proporcionan funcionalidade esencial para tarefas cotiás: coleccións, operacións matemáticas, codificación e decodificación de datos, programación asíncrona, entrada/saída, etc.

🔹 Principais librarías estándar #

LibraríaDescrición
dart:coreTipos básicos (String, int, bool…), coleccións (List, Map, Set) e máis. Esta libraría impórtase automaticamente.
dart:asyncProgramación asíncrona con Future, Stream e outras utilidades.
dart:mathConstantes e funcións matemáticas, xerador de números aleatorios, etc.
dart:convertCodificadores e decodificadores (JSON, UTF-8, Base64…).
dart:ioEntrada/saída para apps de consola, servidores e apps Flutter (non dispoñible en web).
dart:js_interopInteroperabilidade co mundo web (substitúe a dart:html en contextos modernos).

🧭 Outras categorías de librarías #

  • Librarías multiplataforma: dispoñibles en todas as plataformas (web, escritorio, móbil, consola…).
  • Librarías específicas de plataforma:
  • 📱 Native: para apps Flutter ou scripts en Dart VM (dart:io, dart:isolate…).
  • 🌐 Web: para apps que se executan no navegador (dart:html, dart:js_interop…).

📌 Conclusión #

As librarías do núcleo de Dart cobren unha ampla gama de funcionalidades esenciais.
Se necesitas algo máis específico ou avanzado, tamén podes recorrer a paquetes externos dispoñibles en pub.dev, o xestor oficial de paquetes para Dart e Flutter.

🔹 Onde atopar máis información #

Estes apuntamentos ofrecen unha visión xeral. Para detalles máis específicos:

🌐 Outros temas importantes en Dart #

A continuación inclúense temas complementarios e recorrentes ao traballar con Dart, cada un cunha breve descrición e onde atopar información oficial para profundar.

🔸 Serialización JSON #

Permite converter obxectos de Dart a formato JSON e viceversa.
Moi útil para traballar con APIs ou gardar datos.

🔗 Guía oficial sobre JSON en Dart →

🔸 Representación numérica #

Dart fornece tipos e operacións para manipular números enteiros, decimais e binarios.

🔗 Tipos numéricos en Dart →

🔸 APIs de Google #

Dart e Flutter permiten acceder a servizos de Google como Google Drive, Calendar, Maps, etc., mediante paquetes dispoñibles en pub.dev.

🔗 Google APIs para Dart →

🔸 Aplicacións multiplataforma #

Un dos puntos fortes de Dart con Flutter é o desenvolvemento de apps para Android, iOS, web, escritorio e consola cunha única base de código.

🔗 Guía oficial sobre apps multiplataforma →

🔸 Aplicacións de liña de comandos e servidor #

Pódense crear scripts, utilidades de consola ou servidores web usando Dart VM.

🔗 Guía para apps de consola e servidor →

🔸 Aplicacións web #

Dart tamén se pode compilar a JavaScript para crear apps que funcionen directamente no navegador.

🔗 Guía para apps web con Dart →

🔸 Declaracións de contorno (Environment declarations) #

Permiten definir variables de contorno que se poden ler en tempo de execución, moi útil para configuracións como dev, prod, etc.

🔗 Declaracións de contorno en Dart →