Простые приложения на Dart
Простые приложения на Dart
Dart знаком по Flutter, но консольные скрипты (dart run) полезны для утилит и прототипов API. Стандартные библиотеки: dart:io, dart:convert.
Как запускать примеры из главы
- Файл:
bin/main.dartв проектеdart create cliили один файлscript.dart. - Команда:
dart run script.dartилиdart run bin/main.dart. - Нужно: Dart SDK 3+ (
dart --version).
Генератор паролей
Как запустить
- Файл:
password.dart - Команда:
dart run password.dart - Результат: пароль в консоли.
import 'dart:math';
String generatePassword([int length = 16]) {
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\$%';
final rand = Random.secure();
return List.generate(length, (_) => chars[rand.nextInt(chars.length)]).join();
}
void main() => print(generatePassword());
Разбор:
import 'dart:math';подключает генератор случайных чиселRandom.generatePassword([int length = 16])объявляет функцию с необязательным параметром длины и значением по умолчанию16.const chars = ...задаёт фиксированный набор символов, из которых собирается пароль.Random.secure()использует криптографически более стойкий источник случайности по сравнению с обычнымRandom().List.generate(...)создаёт список символов по одному:rand.nextInt(chars.length)выбирает случайный индекс, затем берётся символ изchars..join()склеивает список символов в одну строку и возвращает готовый пароль.
Сортировщик файла
import 'dart:io';
Future<void> sortFile(String input, String output) async {
final lines = await File(input).readAsLines();
final cleaned = lines.map((l) => l.trim()).where((l) => l.isNotEmpty).toList()..sort();
await File(output).writeAsString('${cleaned.join('\n')}\n');
}
Разбор:
readAsLines()читает файл построчно и возвращаетList<String>.map((l) => l.trim())убирает лишние пробелы в начале и конце каждой строки.where((l) => l.isNotEmpty)фильтрует пустые строки, чтобы они не попали в итог.toList()..sort()превращает поток в список и сразу сортирует его через cascade-оператор...writeAsString('${cleaned.join('\n')}\n')записывает отсортированные строки обратно в файл, разделяя их переводами строки.- Функция асинхронная (
Future<void>) и должна вызываться сawait, иначе запись может не успеть завершиться.
Калькулятор
double? calculate(double a, double b, String op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return b == 0 ? null : a / b;
default: return null;
}
}
Разбор:
double?в сигнатуре означает, что функция может вернуть число илиnull, если операция неизвестна/недопустима.switch (op)выбирает ветку по строковому оператору (+,-,*,/).- Ветвь
case '/': return b == 0 ? null : a / b;защищает от деления на ноль через тернарный оператор. default: return null;обрабатывает неподдерживаемые символы операции и даёт безопасный результат вместо падения.- Такая модель возвращает "нет результата" через
null; в production-логике часто добавляют текст ошибки илиResult-тип.
Трекер задач (jsonEncode)
Код ITЗагрузка примера кода…
Разбор:
- Класс
Taskописывает модель задачи —id,title,done. toJson()превращает объект вMap<String, dynamic>, пригодный дляjsonEncode.factory Task.fromJson(...)выполняет обратное преобразование из JSON-словаря в объектTask.- В
load(...)сначала проверяется наличие файлаexists(), чтобы безопасно вернуть пустой список, если файла ещё нет. jsonDecode(...) as Listпарсит JSON-массив, после чего каждый элемент приводится кMap<String, dynamic>и маппится вTask.- Шаблон
toJson/fromJson— базовая схема сериализации для локального хранилища и HTTP API.
HTTP-сервер (HttpServer)
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
final server = await HttpServer.bind('127.0.0.1', 8080);
await for (final req in server) {
req.response
..headers.contentType = ContentType.json
..write(jsonEncode({'ok': true, 'time': DateTime.now().toIso8601String()}))
..close();
}
}
Разбор:
HttpServer.bind('127.0.0.1', 8080)поднимает локальный сервер на порту8080.await for (final req in server)запускает бесконечный асинхронный цикл обработки входящих HTTP-запросов.req.response..headers.contentType = ContentType.jsonвыставляет тип ответаapplication/json.jsonEncode({...})сериализует словарь с полямиokи текущим временем в строку JSON...close()закрывает ответ и отправляет его клиенту; без закрытия соединение может зависнуть.- Это минимальный "health/info" endpoint, который полезен для локальной проверки сервера.
Характерный пример — Future и async/await
Future<int> fetchLength(Uri url) async {
final client = HttpClient();
try {
final req = await client.getUrl(url);
final res = await req.close();
final body = await res.transform(utf8.decoder).join();
return body.length;
} finally {
client.close();
}
}
Разбор:
Future<int>показывает, что результат появится позже и будет числом (int).HttpClientсоздаёт низкоуровневый HTTP-клиент изdart:ioдля запроса по URL.await client.getUrl(url)иawait req.close()по шагам отправляют запрос и получают ответ.res.transform(utf8.decoder).join()конвертирует байты ответа в строку и собирает полный body.return body.length;возвращает длину текста ответа как метрику.- Блок
finally { client.close(); }гарантирует закрытие сокетов даже при ошибке, что защищает от утечек ресурсов.
Асинхронность встроена в язык — основа Flutter и серверного Dart.
См. также: Flutter в разделе 4-code-dev
Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.