Типы данных в Dart

Типизация

Язык программирования Dart строго типизированный

Dart - Строгая типизация

Светлая тема Темная тема
void main() {
  int number = 42;
  
  // Ошибка! Нельзя в число присвоить строку!
  number = "Двадцать восемь";

  // Ошибка! Нельзя в целое число присвоить дробное!
  number = 0.09; 
  
  // Ошибки нет! 28 это число Int
  number = 28;
}

Строгая типизация

При повторном присвоении значения можно использовать только значения того же типа, что и изначально.

Строгая типизация

Предположим, что на складе магазина есть коробки:

Коробки с конфетами и гвоздями

Мы ожидаем, что в коробке с конфетами должны быть только конфеты, а не что-то иное.
Будет крайне грустно и неожиданно, если в этой коробке мы обнаружим гвозди.

Коробка с гвоздями

Так же работает и с переменными. Например, мы хотим быть всегда уверены, что в переменной с типом String всегда будут находиться строки. Поэтому строгая типизация контролирует работу с типами данных.

Переменная типа String Ошибка присваивания в переменную String

Простые типы данных

Тип данных определяет, какие именно значения может хранить объект.

Под каждый тип данных в памяти выделится область для хранения.

Например, если мы указываем тип Integer, то в этой области памяти можно хранить только целые числа и только до определенного размера.

В данном случае для Integer - выделяется 64 битазначения от -9223372036854775808 до 9223372036854775807

Типы данных и память

Dart - Простые типы

Светлая тема Темная тема
void main() {

  int intValue = 42;         // Целое число
  double doubleValue = 3.14; // Дробное число (или с плавающей точкой)
  
  String loveName = "Юля";   // Строка
  bool isHappy = true;       // Логическое значение
  int? emptyValue = null;    // Пустое значение
}

Зачем нужна типизация?

  1. Точное указание того какие мы ожидаем данные в той или иной переменной
  2. В зависимости от выбранного типа, выделяется разный объем памяти в оперативки
  3. IDE легче проанализировать код и указать на ошибки
  4. Интерпретатору легче понять, где мы начинаем делать что-то ни так и указать на это

Округление чисел

Dart - Округление чисел

Светлая тема Темная тема
  // ! Округления чисел
  print(3.25.round());   // 3
  print(3.5.round());    // 4
  print(3.75.round());   // 4
  print((-3.5).round()); // -4

  // floor всегда округляются в меньшую сторону
  print(1.99.floor());    // 1
  print(2.99.floor());    // 2
  print((-2.01).floor()); // -3

  // ceil всегда округляются в большую сторону
  print(1.99.ceil()); // 2
  print(2.001.ceil()); // 3
  print((-1.99).ceil()); // -1

  // truncate отбросить дробную часть
  print(2.01.truncate()); // 2
  print(1.9.truncate()); // 1
  print(0.5.truncate()); // 0

Неявное приведение типов

Неявное приведение типов

Позволяет писать меньше кода при объявлении переменных.
Компилятор может определить тип данных переменной по значению, без явного указания этого типа в коде.

Вместо этого кода

Dart - Явное указание типа

Светлая тема Темная тема
int count = 2;
String name = "Flutter";

Можно написать так (но не рекомендуется)

Dart - Неявное указание типа

Светлая тема Темная тема
var count = 2; // Тип данных num
var name = "Flutter"; // Тип данных String

Родительский тип данных для всех чисел

Важно! В данном случае переменной count будет присвоен тип данных num.
Это родительский тип данных для целых и дробных чисел.

Такой подход называется - динамическая типизация
Кроме var есть возможность вывести типы через dynamic и Object
У всех динамических типов: var dynamic Object есть различия и особенности работы.
Рассмотрим их позже в отдельном занятии.

Dart - Динамическая типизация

Светлая тема Темная тема
var someValueOne = 42;
var someValueTwo = 'String';

dynamic someValueThree = 3.14;
Object someValueFourth = 9999;

int и double

В языке Dart между переменными типа int и double можно выполнять арифметические операции без ошибок приведения типов.

Результат будет приведён к типу double, чтобы сохранить дробную часть и точность вычислений.

Dart - Операции с int и double

Светлая тема Темная тема
int x = 1;
double y = 2.2;

print(x + y); // 3.2
print(x * y); // 2.2
print(x / y); // 0.45454545454545453
print(x % y); // 1.0

Явное приведение типов

Явное приведение типов

Для преобразования данных одного типа в другой можно использовать встроенные функции, которые есть у базовых типов

.toInt() .toString() .toDouble()

Dart - Явное приведение

Светлая тема Темная тема
void main() {
  var count = 2; // Неявно вывелся тип num
  
  int intValue = count.toInt(); // Число 2
  String stringValue = count.toString(); // Строка "2"
  double doubleValue = count.toDouble(); // Дробное 2.0
}

Приведение строки в число

Чтобы преобразовать строку в целое число, можно использовать метод int.parse()
Этот метод принимает строковое значение и возвращает его в виде целого числа.

Dart - String to Int

Светлая тема Темная тема
main() {
  String text = "123";
  int intValue = int.parse(text);

  print(intValue * 2); // 123 * 2 = 246
}

Объекты и вызов через точку

Объект

Dart это ООП язык и всё здесь является объектом (число, строка, переменная)

Объект из реальной жизни обладает двумя важными характеристиками:

  1. СВОЙСТВА (Количественно-Качественная характеристика)
  2. МЕТОДЫ (Действия которые этот объект может делать)

Например

Студент это Объект
У него есть свойства: возраст, рост, цвет глаз, …
У него есть методы: учиться, спать, играть в настолки, …

Переносим эти понятия в мир программирования.
у String (строк) есть свойства и методы
у Num (чисел) тоже есть свойства и методы, потому что это тоже объекты

Точечная нотация

Доступ до свойств и методов делается через точку .
Пишем название объекта, потом ставим точку и выбираем нужные операции

Точечная нотация Свойства и методы

Рассмотрим несколько свойств и методов.
Однако этих методов великое множество, все их рассматривать прямо сейчас смысла нет.
Они изучаются на практике, при решение конкретной проблемы.

Dart - Свойства и методы

Светлая тема Темная тема
void main() {
  String myStringObject = 'String is an Object';
  num myNumObject = -42.42;
  
  // ? Свойства строки
  print(myStringObject.length); // Длина строки
  print(myStringObject.runtimeType); // Тип объекта

  // ? Методы строки
  print(myStringObject.contains('is')); // Cодержит ли строка подстроку 'is'
  print(myStringObject.toUpperCase()); // Сделать все буквы заглавными

  // ? Методы числа
  print(myNumObject.toString()); // Сделать число строкой
  print(myNumObject.abs()); // Вернуть модуль числа
  print(myNumObject.ceil()); // Округлить число

  // ? Свойства числа
  print(myNumObject.toInt().isEven); // четное ли число
  print(myNumObject.toInt().isOdd); // не четное ли число
  print(myNumObject.isNegative); // отрицательное ли число
}