Какие особенности языка Dart ты знаешь?

Ответ

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, где из него делают красивые мобильные, десктопные и веб-приложения. Учи, не пожалеешь.