Существуют следующие встроенные типы данных:
int a = 5;
int hex = 0xDEAFF; // 64 бита -2⁶³ до 2⁶³-1 (при переводе в JavaScript -2⁵³ до 2⁵³-1)
int double c = 30.5; // в соответствии со стандартом IEEE 754 (64 бита)
var b = 10; // возможно автоматическое выведение типа
var d = 1.1; // возможно автоматическое выведение типа
var exponents = 1.42e5; // возможно автоматическое выведение типа (эквивалентно 142000.0)
num x = 11; // этому типу можно присваивать int и double, есть нюансы с округлениями и сравнениями
Строки в Dart представляют собой последовательность символов в кодировке UTF-16. Неизменяемый (immutable) тип данных.
String s1 = 'Мама мыла раму';
var s2 = "Мама мыла две рамы";
var s3 = '''Многострочная
строка''';
var s = s1[0]; // обращение к первому символу строки - читать его можно, изменять нельзя
bool yes = true;
var no = false;
Списки – позиционно упорядоченные коллекции объектов. В отличие от строк, списки можно модифицировать на месте путем присваивания по индексу или вызовом некоторых списковых методов.
var myList1 = [1, 2, 3];
List<int> myList2 = [1, 2, 3];
var myList3 = <int>[]; // пустой список
Поскольку записи анонимны, то при их объявлении не используется упоминание типа Record.
(int, String) myRecord1 = (10, 'smile-1');
var myRecord2 = (11, 'smile-2');
// объявления с именованными полями:
({int cost, String smile}) myRecord3 = (cost: 10, smile: 'smile-3');
var myRecord4 = (cost: 12, smile: 'smile-4');
Именованные поля при объявлении записи задаются посредством фигурных скобок и могут чередоваться с неименованными (но только в правой части выражения).
var myRecord5 = (3.14, cost: 10, smile: 'smile-5', 22);
(double, int, {int cost, String smile}) myRecord6 = (3.14, cost: 10, smile: 'smile-6', 33);
Множество – неупорядоченная совокупность объектов одного типа данных, в которой не может быть дубликатов.
var mySet1 = <int>{1, 2, 5, 5, 5, 6, 7, 8};
Set<int> mySet2 = {}; // пустое множество
var mySet3 = <int>{}; // пустое множество
Map представляет из себя объект, который связывает ключи и значения. Чаще этот тип данных называют просто «карты».
var myMap1 = <int, String>{
1: 'мама',
2: 'мыла',
3: 'раму'
};
var myMap2 = Map<String, int>(); // пустой объект
var myMap3 = <String, int>{}; // пустой объект
Runes аналогичны строкам с тем отличием, что они представляют собой последовательность символов в кодировке UTF-32, а не UTF-16. В этом случае каждый символ представляет собой запись вида '\uXXXX', где ХХХХ четырех числовое значение в шестнадцатеричной системе счисления. Например, букве «П» соответствует представление '\u041F'.
Объекты типа Symbol представляют собой некоторые идентификаторы для ссылки на различные элементы API, такие как библиотеки или классы. Используются нечасто.
var mySymbol = #myAPI;
print(mySymbol); // Symbol("myAPI")
Начиная с версии Dart 2.12 все объявляемы переменные создаются как null-safety, то есть переменной объявляемого типа данных нельзя присвоить значение null. Также, если мы не проинициализировали переменную до ее использования, компилятор выведет ошибку.
Для того, чтобы дать возможность переменной ссылаться на null (указать, что объявляемая переменная не является null-safety) необходимо явно указать компилятору используя символ «?» сразу после объявления типа переменной:
void main(List<String> arguments) {
Cat firstCat = null; // error: A value of type 'Null' can't be assigned to a variable of type 'Cat'
Cat? secondCat = null; // ок
}
Для работы с переменными, могущими получать значения null Dart предоставляет несколько возможностей в виде операторов: «?.», «??» и «!.»:
Существуют два вида dynamic и Object. Таким переменным, в процессе выполнения программы, можно присваивать значения разных типов:
dynamic myValue1 = 3;
myValue1 = 4.10;
myValue1 = 'oO';
myValue1 = [3, 4, 'w'];
myValue1 = null;
Object myValue2 = 3;
myValue2 = 4.10;
myValue2 = 'oO';
myValue2 = [3, 4, 'w'];
myValue2 = null; // значение null возможно только при использовании Object?
Разница между этими типами только в том, что dynamic – статический тип, который является базовым для всех других типов, как и Object, но отличается от них тем, что разрешает все операции. Иными словами, при вызове несуществующего метода, тип dynamic выбросит исключение при выполнении программы. А если используем Object, то при попытке вызова несуществующего метода программа выдаст ошибку еще на этапе компиляции и сборки.