diegoRodicio

View Categories

🧠 Para saber máis

Tempo de lectura estimado: 5 minutos

Estes apartados son de ampliación e consulta. Non precisamos dominar todas estas variantes para comezar con Flutter.

🏷️ typedef: poñer nome a un tipo

Un alias dá un nome máis cómodo a un tipo existente; non crea un tipo novo. Por exemplo, podemos poñer nome ao tipo dun callback. En Flutter atoparemos alias como VoidCallback.

🔗 Ver o código en DartPad — https://dartpad.dev/?id=33e80e89a3a5aa835bd99b6ac2079c65

📚 Documentación de typedef — https://dart.dev/language/typedefs.

🧪 Crear elementos xenéricos

Xa usamos xenéricos en List<String> ou Future<String>. Tamén podemos definir unha clase que traballe cun tipo indicado ao usala. Este exemplo é para volver a el despois das clases e dos construtores do Tema 2.2.

🔗 Ver o código en DartPad — https://dartpad.dev/?id=cf17c04184d9043c1016821290e9d48b

📚 Documentación de xenéricos — https://dart.dev/language/generics.

🧩 Patróns e desestruturación

Un patrón permite comprobar a forma dun dato e extraer partes del. A desestruturación garda esas partes en variables. Pódese usar con rexistros, listas, mapas ou nun switch. if-case executa un bloque cando o dato encaixa nun patrón.

final director = (nome: 'Diego Rodicio', cargo: 'Director');
final (nome: nome, cargo: cargo) = director; // Extraemos os dous campos.
print('$nome: $cargo');

📚 Patróns — https://dart.dev/language/patterns e if-case — https://dart.dev/language/branches#if-case.

🔎 Comprobar tipos con is e as

Xa vimos Object e dynamic no apartado de variables. Para traballar cun dato de tipo xeral podemos comprobar que tipo de valor contén.

  • is comproba o tipo. Dentro dun if, Dart pode usar esa información para permitir operacións dese tipo.
  • as esixe que o valor sexa compatible co tipo indicado (cast). Se non o é, falla ao executar. Non transforma un texto nun número; para iso usamos parse() ou tryParse().
Object dato = 'Diego';
if (dato is String) {
  print(dato.toUpperCase()); // Aquí Dart sabe que é un String.
}
// '8' as int fallaría: ese valor é un texto, non un int.

📚 Consulta: sistema de tipos — https://dart.dev/language/type-system e comprobación de tipos — https://dart.dev/language/operators#type-test-operators.

🌱 Xeradores

Un xerador produce unha secuencia: sync* devolve un Iterable e async* devolve un Stream. yield entrega un elemento; yield* entrega os elementos doutra secuencia.

📚 Xeradores — https://dart.dev/language/functions#generators.

🔄 Outras formas de usar Future e Stream

then() recibe o resultado dun Future, catchError() trata o erro e whenComplete() permite facer unha acción cando remata. Son alternativas ás formas con await e try/catch/finally, con detalles propios no tratamento de erros.

Stream.listen() rexistra callbacks para recibir datos e devolve unha subscrición. Se deixamos de necesitala, podemos cancelala con cancel().

📚 Future — https://api.dart.dev/dart-async/Future-class.html e StreamSubscription — https://api.dart.dev/dart-async/StreamSubscription-class.html.

⚙️ Isolates e bucle de eventos

O bucle de eventos atende tarefas e eventos pendentes. Un isolate ten a súa propia memoria e pode executar traballo separado doutro isolate. Úsase, por exemplo, para cálculos custosos; a comunicación pode facerse con mensaxes a través de portos.

Non necesitamos crear isolates para unha espera de rede con await.

📚 Concorrencia e isolates — https://dart.dev/language/concurrency.

🧰 Máis operacións con coleccións

Ademais das operacións xa vistas, un Set permite facer unións e interseccións. Convén consultar estas opcións cando as necesitemos, en vez de memorizar todos os métodos.

📚 List — https://api.dart.dev/dart-core/List-class.html, Map — https://api.dart.dev/dart-core/Map-class.html e Set — https://api.dart.dev/dart-core/Set-class.html.

➕ Outros operadores e instrucións

  • Bits: &, |, ^ e os desprazamentos operan sobre a representación binaria dos enteiros.
  • Cascadas (..): permiten facer varias operacións sobre o mesmo obxecto sen repetir a variable.
  • Etiquetas: permiten indicar a que bucle se refire un break ou continue en bucles aniñados.
  • assert: comproba unha condición durante o desenvolvemento cando as asercións están activadas. Non substitúe a validación da entrada: pode estar desactivado.
  • rethrow: dentro dun catch, volve propagar a excepción que se recibiu.

📚 Operadores e precedencia — https://dart.dev/language/operators, bucles — https://dart.dev/language/loops e excepcións e assert — https://dart.dev/language/error-handling.

🕓 Inicialización aprazada e valores ignorados

Un inicializador con late, como late final dato = calcularDato();, avalíase cando se le a variable por primeira vez. É diferente de declarar unha variable e asignala máis tarde.

_ pode indicar que non imos usar un parámetro ou unha variable local. Non é o mesmo que un nome como _dato, relacionado coa privacidade que veremos no Tema 2.2.

📚 late — https://dart.dev/language/variables#late-variables e variables comodín — https://dart.dev/language/variables#wildcard-variables.

🔣 Unicode e paquetes

Un carácter visible, como un emoji, pode ocupar varias unidades de texto. Por iso String.length non sempre coincide coa cantidade de caracteres que vemos. O paquete characters permite traballar con esas unidades visibles, chamadas grafemas.

Nun proxecto Dart podemos engadilo con dart pub add characters. As dependencias quedan recollidas en pubspec.yaml e impórtanse cunha ruta package:.

📚 Texto e caracteres — https://dart.dev/language/built-in-types#characters, paquete characters — https://pub.dev/packages/characters e dependencias — https://dart.dev/tools/pub/dependencies.

📚 Importacións e anotacións

Unha importación pode usar as para asignar un prefixo, show para importar só certos nomes ou hide para excluílos.

As anotacións achegan información ao código. Por exemplo, @override indica que sobrescribimos un membro herdado; veremos isto no Tema 2.2. Tamén se poden crear anotacións propias.

📚 Bibliotecas e importacións — https://dart.dev/language/libraries e anotacións — https://dart.dev/language/metadata.

🖥️ Argumentos de main

main pode recibir unha List<String> cos argumentos escritos ao lanzar o programa. Eses argumentos son distintos das liñas que lemos despois con stdin.

📚 A función main — https://dart.dev/language/functions#the-main-function.