Ответ
Dart — это современный язык с сильной типизацией, разработанный для клиентских приложений, особенно для Flutter. Его ключевые особенности:
1. Null Safety (по умолчанию): Типы не допускают null по умолчанию. Для nullable-типов используется суффикс ?.
String name = 'Alice'; // Не может быть null
String? nickname = null; // Может быть null
2. Операторы для работы с null:
??(оператор если-null):String displayName = nickname ?? name;?.(условный доступ):int? length = nickname?.length;!(оператор утверждения non-null):String sureName = nickname!;// Может выбросить исключение
3. Функции как объекты первого класса и лямбда-выражения:
void printMessage(String msg) => print(msg);
Function logger = printMessage;
// Лямбда
final multiply = (int a, int b) => a * b;
4. Mixins для повторного использования кода: Позволяют добавлять функциональность в классы без использования наследования.
mixin ValidationMixin {
bool isValidEmail(String email) => email.contains('@');
}
class UserForm with ValidationMixin {}
5. Асинхронность через Future и async/await:
Future<String> fetchUserData() async {
final response = await http.get(Uri.parse('https://api.example.com/user'));
return response.body;
}
6. Генераторы для ленивых последовательностей:
Iterable<int> getRange(int start, int end) sync* {
for (int i = start; i <= end; i++) {
yield i;
}
}
7. Изоляты (Isolates) для параллелизма: Вместо потоков Dart использует изоляты с разделяемой памятью, что исключает состояние гонки.
Ответ 18+ 🔞
А, Dart, ёпта! Ну, это тот самый язык, который придумали, когда поняли, что писать на JavaScript — это как пытаться собрать IKEA без инструкции, только хуже. Язык с характером, блядь.
Смотри, главная его фишка — Null Safety. Это когда по умолчанию переменная не может быть этой самой... нулём, пустотой, ничем. Чтобы объявить такую хитрожопую переменную, которая может быть ничем, надо поставить вопросик. Без этого — ни-ни. Идея, в принципе, охуенная, потому что половина багов в мире от того, что где-то null вылез, где его не ждали.
String name = 'Alice'; // Тут всё чётко, имя есть. Не может быть `null`.
String? nickname = null; // А это уже наш шаловливый вариант. Может быть, а может и не быть. Подозрение ёбать чувствую к таким.
Дальше идут операторы, чтобы с этой неопределённостью бороться. ?? — это типа «бери это, а если это — хуйня (null), то бери вот то». ?. — это осторожный доступ: «если объект не null, спроси у него длину, а если null — сам понимаешь...». А вот ! — это уже жесткая уверенность: «я, сука, знаю, что тут не null!». Если ошибся — будет тебе хиросима в рантайме, сам виноват.
String displayName = nickname ?? name; // Берём ник, а если его нет — имя.
int? length = nickname?.length; // Спросим длину, если ник есть.
String sureName = nickname!; // А вот тут ты уверен, как в завтрашнем дне. Рискованный пидорас.
Дальше — функции. Их можно пихать в переменные, как бутерброд в рот, они объекты первого класса. И лямбды — короткие, как шорты.
void printMessage(String msg) => print(msg); // Стрелочка, всё коротко и ясно.
Function logger = printMessage; // Засунули функцию в переменную. Нормально.
// Лямбда — вообще красота.
final multiply = (int a, int b) => a * b; // Всё, функция готова. Ебать копать, удобно.
А вот Mixins — это вообще магия, ядрёна вошь. Наследование — это когда один родитель, и всё. А миксины — это как взять шмотки с разных вешалок и собрать себе уникальный прикид. Классу можно добавить функциональность из кучи мест, без этой всей иерархии «папа-сын-внук».
mixin ValidationMixin {
bool isValidEmail(String email) => email.contains('@'); // Миксин с одной полезной функцией.
}
class UserForm with ValidationMixin {} // И вот наш класс уже умеет проверять почту. Волшебство, блядь.
Асинхронность — через Future и async/await. Не надо этих адских колбэков, где мозг сломаешь. Написал async, поставил await перед долгой операцией — и код читается, как книга, сверху вниз.
Future<String> fetchUserData() async {
final response = await http.get(Uri.parse('https://api.example.com/user')); // Ждём ответа, не дергаясь.
return response.body; // Вернули, когда дождались.
}
Ещё есть генераторы (sync*, yield). Нужны, чтобы лениво создавать последовательности. Не генерируй всё сразу, а выдавай по элементу, когда попросят. Экономия памяти — овердохуища.
Iterable<int> getRange(int start, int end) sync* {
for (int i = start; i <= end; i++) {
yield i; // Вот тебе один, на, потом следующий, когда надо будет.
}
}
И вишенка на торте — Изоляты (Isolates). Потоки — это боль, гонки, мьютексы, голова болит. В Dart вместо потоков — изоляты. У каждого своя память, они не шастают по чужой. Общаются через сообщения. Состояние гонки? Да похуй, его в принципе не может возникнуть. Гениально и просто, как топор.
Короче, Dart — это не какой-нибудь пидарас шерстяной, а серьёзный инструмент. Особенно для Flutter, где из него делают красивые мобильные, десктопные и веб-приложения. Учи, не пожалеешь.