Introducción a Dart
Una breve introducción a los programas de Dart y conceptos importantes.
Esta página proporciona una breve introducción al lenguaje Dart a través de muestras de sus principales características.
Para obtener más información sobre el lenguaje Dart, visita las páginas de temas individuales en profundidad que figuran en Language en el menú lateral izquierdo.
Para obtener cobertura de las librerías principales de Dart, consulta la documentación de las librerías principales. También puedes consultar la hoja de referencia rápida (cheatsheet) de Dart, para una introducción más interactiva.
Hola Mundo
#Cada aplicación requiere la función de nivel superior main(), donde comienza la ejecución.
Las funciones que no retornan explícitamente un valor tienen el tipo de retorno void.
Para mostrar texto en la consola, puedes usar la función de nivel superior print():
void main() {
print('Hello, World!');
}
Lee más sobre la función main() en Dart,
incluyendo parámetros opcionales para los argumentos de la línea de comandos.
Variables
#Incluso en el código Dart con seguridad de tipos (type-safe),
puedes declarar la mayoría de las variables sin especificar explícitamente su tipo usando var.
Gracias a la inferencia de tipos, los tipos de estas variables se determinan por sus valores iniciales:
var name = 'Voyager I';
var year = 1977;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg',
};
Lee más sobre variables en Dart,
incluyendo valores por defecto, las palabras clave final y const, y tipos estáticos.
Sentencias de control de flujo
#Dart admite las sentencias de control de flujo habituales:
if (year >= 2001) {
print('21st century');
} else if (year >= 1901) {
print('20th century');
}
for (final object in flybyObjects) {
print(object);
}
for (int month = 1; month <= 12; month++) {
print(month);
}
while (year < 2016) {
year += 1;
}
Lee más sobre las sentencias de control de flujo en Dart,
incluyendo break y continue,
switch y case,
y assert.
Funciones
#Recomendamos especificar los tipos de los argumentos de cada función y su valor de retorno:
int fibonacci(int n) {
if (n == 0 || n == 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
var result = fibonacci(20);
Una sintaxis abreviada => (flecha / arrow) es útil para funciones que
contienen una sola sentencia.
Esta sintaxis es especialmente útil al pasar funciones anónimas como argumentos:
flybyObjects.where((name) => name.contains('turn')).forEach(print);
Además de mostrar una función anónima (el argumento para where()),
este código muestra que puedes usar una función como argumento:
la función de nivel superior print() es un argumento para forEach().
Lee más sobre funciones en Dart, incluyendo parámetros opcionales, valores de parámetros por defecto y alcance léxico.
Comentarios
#Los comentarios de Dart suelen comenzar con //.
// This is a normal, one-line comment.
/// This is a documentation comment, used to document libraries,
/// classes, and their members. Tools like IDEs and dartdoc treat
/// doc comments specially.
/* Comments like these are also supported. */
Lee más sobre comentarios en Dart, incluyendo cómo funcionan las herramientas de documentación.
Importaciones
#Para acceder a las APIs definidas en otras librerías, usa import.
// Importing core libraries
import 'dart:math';
// Importing libraries from external packages
import 'package:test/test.dart';
// Importing files
import 'path/to/my_other_file.dart';
Lee más
sobre las librerías y la visibilidad en Dart,
incluyendo prefijos de librería, show y hide,
y la carga diferida mediante la palabra clave deferred.
Clases
#Aquí tienes un ejemplo de una clase con tres propiedades, dos constructores y un método. Una de las propiedades no se puede establecer directamente, por lo que está definida mediante un método getter (en lugar de una variable). El método utiliza la interpolación de cadenas para imprimir las equivalencias de cadena de las variables dentro de los literales de cadena.
class Spacecraft {
String name;
DateTime? launchDate;
// Read-only non-final property
int? get launchYear => launchDate?.year;
// Constructor, with syntactic sugar for assignment to members.
Spacecraft(this.name, this.launchDate) {
// Initialization code goes here.
}
// Named constructor that forwards to the default one.
Spacecraft.unlaunched(String name) : this(name, null);
// Method.
void describe() {
print('Spacecraft: $name');
// Type promotion doesn't work on getters.
var launchDate = this.launchDate;
if (launchDate != null) {
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}
Lee más sobre cadenas (strings),
incluyendo interpolación de cadenas, literales, expresiones y el método toString().
Podrías usar la clase Spacecraft de esta manera:
var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();
var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();
Lee más sobre clases en Dart,
incluyendo listas de inicializadores, las palabras clave opcionales new y const, constructores de redireccionamiento,
constructores factory, getters, setters y mucho más.
Enums
#Los enums son una forma de enumerar un conjunto predefinido de valores o instancias de manera que se garantice que no pueda haber otras instancias de ese tipo.
Aquí hay un ejemplo de un enum simple que define
una lista sencilla de tipos de planetas predefinidos:
enum PlanetType { terrestrial, gas, ice }
Aquí hay un ejemplo de una declaración de enum mejorado (enhanced enum) de una clase que describe planetas, con un conjunto definido de instancias constantes, a saber, los planetas de nuestro propio sistema solar.
/// Enum that enumerates the different planets in our solar system
/// and some of their properties.
enum Planet {
mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
// ···
uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);
/// A constant generating constructor
const Planet({
required this.planetType,
required this.moons,
required this.hasRings,
});
/// All instance variables are final
final PlanetType planetType;
final int moons;
final bool hasRings;
/// Enhanced enums support getters and other methods
bool get isGiant =>
planetType == PlanetType.gas || planetType == PlanetType.ice;
}
Podrías usar el enum Planet de esta manera:
final yourPlanet = Planet.earth;
if (!yourPlanet.isGiant) {
print('Your planet is not a "giant planet".');
}
Cuando el compilador puede inferir el tipo de enum a partir del contexto,
puedes usar la sintaxis abreviada de punto (dot-shorthand) más concisa para acceder a los valores del enum.
En lugar de escribir el nombre completo EnumName.value,
simplemente puedes escribir .value. Esto puede hacer que tu código sea más limpio
y fácil de leer.
Por ejemplo, al declarar una variable con un tipo explícito de Planet,
puedes omitir el nombre del enum porque
el tipo de Planet ya está establecido:
// Instead of the full, explicit syntax:
Planet myPlanet = Planet.venus;
// You can use a dot shorthand:
Planet myPlanet = .venus;
Los accesos abreviados con punto no se limitan a las declaraciones de variables. También se pueden usar en contextos como argumentos de funciones y casos de switch donde el tipo de enum está claro para el compilador.
Lee más sobre enums en Dart, incluyendo requisitos de enums mejorados (enhanced enums), propiedades introducidas automáticamente, acceso a nombres de valores enumerados, soporte para sentencias switch y mucho más. Lee más sobre la sintaxis abreviada de punto (dot-shorthand).
Herencia
#Dart tiene herencia simple.
class Orbiter extends Spacecraft {
double altitude;
Orbiter(super.name, DateTime super.launchDate, this.altitude);
}
Lee más
sobre cómo extender clases, la anotación opcional @override y más.
Mixins
#Los mixins son una forma de reutilizar código en múltiples jerarquías de clases. La siguiente es una declaración de mixin:
mixin Piloted {
int astronauts = 1;
void describeCrew() {
print('Number of astronauts: $astronauts');
}
}
Para agregar las capacidades de un mixin a una clase, simplemente extiende la clase con el mixin.
class PilotedCraft extends Spacecraft with Piloted {
// ···
}
PilotedCraft ahora tiene el campo astronauts así como el método describeCrew().
Lee más sobre mixins.
Interfaces y clases abstractas
#Todas las clases definen implícitamente una interfaz. Por lo tanto, puedes implementar cualquier clase.
class MockSpaceship implements Spacecraft {
// ···
}
Lee más sobre interfaces implícitas, o
sobre la palabra clave explícita interface.
Puedes crear una clase abstracta para ser extendida (o implementada) por una clase concreta. Las clases abstractas pueden contener métodos abstractos (con cuerpos vacíos).
abstract class Describable {
void describe();
void describeWithEmphasis() {
print('=========');
describe();
print('=========');
}
}
Cualquier clase que extienda Describable tiene el método describeWithEmphasis(),
el cual llama a la implementación de describe() de la clase que la extiende.
Lee más sobre clases y métodos abstractos.
Async
#Evita el infierno de los callbacks (callback hell) y haz que tu código sea mucho más legible
usando async y await.
const oneSecond = Duration(seconds: 1);
// ···
Future<void> printWithDelay(String message) async {
await Future.delayed(oneSecond);
print(message);
}
El método anterior es equivalente a:
Future<void> printWithDelay(String message) {
return Future.delayed(oneSecond).then((_) {
print(message);
});
}
Como muestra el siguiente ejemplo, async y await ayudan a hacer que el código asíncrono
sea fácil de leer.
Future<void> createDescriptions(Iterable<String> objects) async {
for (final object in objects) {
try {
var file = File('$object.txt');
if (await file.exists()) {
var modified = await file.lastModified();
print(
'File for $object already exists. It was modified on $modified.',
);
continue;
}
await file.create();
await file.writeAsString('Start describing $object in this file.');
} on IOException catch (e) {
print('Cannot create description for $object: $e');
}
}
}
También puedes usar async*, lo que te brinda una forma agradable y legible de construir streams.
Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
for (final object in objects) {
await Future.delayed(oneSecond);
yield '${craft.name} flies by $object';
}
}
Lee más sobre
el soporte de asincronía, incluyendo funciones async, Future,
Stream
y el bucle asíncrono (await for).
Excepciones
#Para lanzar una excepción, usa throw:
if (astronauts == 0) {
throw StateError('No astronauts.');
}
Para capturar una excepción, usa una sentencia try con on o catch (o ambos):
Future<void> describeFlybyObjects(List<String> flybyObjects) async {
try {
for (final object in flybyObjects) {
var description = await File('$object.txt').readAsString();
print(description);
}
} on IOException catch (e) {
print('Could not describe object: $e');
} finally {
flybyObjects.clear();
}
}
Ten en cuenta que el código anterior es asíncrono;
try funciona tanto para código síncrono como asíncrono en una función async.
Lee más sobre excepciones,
incluyendo rastreos de pila (stack traces), rethrow,
y la diferencia entre Error y Exception.
Conceptos importantes
#A medida que continúas aprendiendo sobre el lenguaje Dart, ten en cuenta estos hechos y conceptos:
-
Todo lo que puedes colocar en una variable es un objeto, y cada objeto es una instancia de una clase. Incluso los números, las funciones y
nullson objetos. Con la excepción denull(si habilitas sound null safety), todos los objetos heredan de la claseObject. -
Aunque Dart es fuertemente tipado, las anotaciones de tipo son opcionales porque Dart puede inferir los tipos. En
var number = 101, se infiere quenumberes de tipoint. -
Las variables no pueden contener
nulla menos que indiques que sí pueden. Puedes hacer que una variable sea anulable agregando un signo de interrogación (?) al final de su tipo. Por ejemplo, una variable de tipoint?podría ser un entero o podría sernull. Si sabes que una expresión nunca se evalúa comonullpero Dart no está de acuerdo, puedes agregar!para afirmar que no es nulo (y para lanzar una excepción si lo es). Un ejemplo:int x = nullableButNotNullInt! -
Cuando quieras decir explícitamente que se permite cualquier tipo, usa el tipo
Object?(si has habilitado null safety),Object, o (si debes posponer la comprobación de tipos hasta el tiempo de ejecución) el tipo especialdynamic. -
Dart admite tipos genéricos, como
List<int>(una lista de enteros) oList<Object>(una lista de objetos de cualquier tipo). -
Dart admite funciones de nivel superior (como
main()), así como funciones vinculadas a una clase u objeto (métodos estáticos (static) e instancia, respectivamente). También puedes crear funciones dentro de funciones (funciones anidadas o locales). -
Del mismo modo, Dart admite variables de nivel superior, así como variables vinculadas a una clase u objeto (variables estáticas y de instancia). Las variables de instancia a veces se conocen como campos o propiedades.
-
A diferencia de Java, Dart no tiene las palabras clave
public,protectedyprivate. Si un identificador comienza con un guion bajo (_), es privado para su librería. Para obtener más detalles, consulta Librerías e importaciones. -
Los identificadores pueden comenzar con una letra o un guion bajo (
_), seguidos de cualquier combinación de esos caracteres más dígitos. -
Dart tiene tanto expresiones (que tienen valores en tiempo de ejecución) como sentencias (que no los tienen). Por ejemplo, la expresión condicional
condition ? expr1 : expr2tiene un valor deexpr1oexpr2. Compara eso con una sentencia if-else, que no tiene valor. Una sentencia a menudo contiene una o más expresiones, pero una expresión no puede contener directamente una sentencia. -
Las herramientas de Dart pueden reportar dos tipos de problemas: advertencias (warnings) y errores. Las advertencias son solo indicaciones de que es posible que tu código no funcione, pero no impiden que tu programa se ejecute. Los errores pueden ser de tiempo de compilación o de tiempo de ejecución. Un error en tiempo de compilación impide que el código se ejecute en absoluto; un error en tiempo de ejecución da como resultado el lanzamiento de una excepción mientras se ejecuta el código.
Recursos adicionales
#Puedes encontrar más documentación y ejemplos de código en la documentación de las librerías principales y en la referencia de la API de Dart. El código de este sitio sigue las convenciones de la guía de estilo de Dart.
A menos que se indique lo contrario, la documentación en este sitio refleja Dart 3.12.2. Página actualizada por última vez el 2026-05-12. Ver fuente oreportar un problema.