Порхающий дротик
Fluttering Dart: встроенные типы данных
Болты и гайки Дартса
В проектах Flutter можно использовать как платформенно-зависимый, так и кроссплатформенный код. Последний написан на Dart, и для создания приложений Flutter требуются некоторые базовые знания Dart.
Цель Fluttering Dart - изучить фундаментальные знания и раскрыть советы и рекомендации мощного языка программирования, который воплощает в жизнь Flutter.
В этой первой части мы познакомимся со встроенными типами данных Dart.
Примеры кода можно опробовать и поиграть с помощью DartPad.
Встроенные типы данных
Тип данных - это особый вид информации, позволяющий выполнять определенные операции.
Числа в Dart могут быть двух типов:
- int eger - представляют собой целые числа не более 64 бит (в зависимости от платформы)
- 64-битная двойная точность с плавающей запятой (стандарт IEEE 754) - используется для представления чисел с десятичными знаками.
Их супертип - тип число.
Все числа также являются объектами и у каждого есть свои методы.
void main() { int x = 4; print(x.toRadixString(2) == '100'); double y = 19.861004; print(y.toStringAsFixed(4) == '19.8610'); }
В приведенном выше примере мы сначала определяем int с именем x, которое получает значение 4, а затем используем int метод toRadixString для получения двоичного представления x (в виде строки). Мы могли бы использовать, например, шестнадцатеричное основание - 16 - вместо 2. Равенство между представлением 4 в двоичной базе: '100' - истинно, и это то, что отобразит метод print.
Затем мы определяем double с именем y и присваиваем ему значение (19.8610). Затем мы используем встроенную функцию toStringAsFixed double, чтобы получить только 4 десятичных разряда y (также в виде строки). Равенство также выполняется, поэтому метод print снова отобразит true.
Строка - это последовательность кодовых единиц UTF-16.
Строки используются для представления всего, что вы можете написать или выразить в виде утверждения, а также отдельных символов. Для представления специальных символов вы можете проверить Руны ниже.
Чтобы создать строку, мы можем использовать одинарные '
или двойные "
кавычки (неважно, какие из них, если мы единообразны во всем коде).
Строковая интерполяция встроена в Dart. Выражения можно встраивать в строки с помощью формы ${expression}
, и они вычисляются, когда мы их используем. Если выражение является идентификатором, мы можем опустить {}
:
void main() { String dartLang = 'Dart'; String javaLang = 'Java'; print('Saying that $dartLang is identical to $javaLang might be a bit too much... At least when we count the letters in their names we get ${dartLang.length} in both cases.'); }
Многострочные строки можно создавать с помощью тройных кавычек (одинарных или двойных):
void main() { String multiLine = ''' This is nice! '''; print('$multiLine'); }
Конкатенация строк выполняется просто путем размещения строковых литералов рядом друг с другом без знака +:
void main() { String concatenated = 'This ''is ' '(kind ''of) ' 'odd' '...'; print('$concatenated'); }
Тип bool представляет собой логические значения.
У него всего два значения: истина или ложь.
Такие условия, как if, while или assert, можно использовать только с bool.
Типовая безопасность Dart означает, что мы не можем использовать такой код, как if(nonBooleanValue)
или assert(nonBooleanValue)
. Вместо этого явно проверьте значения, например:
void main() { String emptyName = ''; if(emptyName.isEmpty) { print('Like the name says, it is empty!'); } String nullName; if(nullName == null) { print('Like the name says, it is null!'); } }
Список - часто используемый тип коллекции.
Массивы (для людей, пришедших из других языков программирования) являются объектами списка.
В приведенном ниже примере используются как литерал списка, так и конструктор списка. По возможности рекомендуется использовать литералы:
void main() { // the literal way List oneWay = [1,2,3]; // the constructor way List orAnother = List<int>(3); }
Карта - еще один часто используемый тип сбора.
В приведенном ниже примере используются как литерал карты, так и конструктор карты. По возможности рекомендуется использовать литералы:
void main() { // the literal way Map oneWay = {'a': 0, 'b': 1, 'c': 2}; // the constructor way Map orAnother = Map<String, int>(); }
Наборы в Dart - это неупорядоченные коллекции уникальных предметов.
Чтобы создать пустой набор, используйте {}
, которому предшествует аргумент типа, или назначьте {}
переменной типа Set.
Синтаксис литералов map аналогичен синтаксису литералов набора. Поскольку литералы Map были первыми в Dart, {}
по умолчанию используется этот тип. Если вы забыли добавить аннотацию типа в {}
или не назначили {}
переменной типа Set, то по умолчанию Dart создает объект типа Map ‹динамический, динамический ›.
void main() { // the literal way Set oneWay = {}; // the constructor way Set orAnother = <String>{}; Set petTypes = {'cat', 'dog', 'bird', 'reptile', 'other'}; print('There are ${petTypes.length} pet types defined.'); }
Символ представляют собой оператор или идентификатор.
Их можно создать с помощью конструктора Symbol (' name' ) или символьного литерала #
Символы используются редко. Они отлично подходят для создания API-интерфейсов, которые ссылаются на идентификаторы по имени, потому что минификация изменяет имена идентификаторов, но не символы идентификаторов.
Символы, созданные с таким же именем, равны:
void main() { print(Symbol('a') == #a); // the above prints true }
Руны - это кодовые точки UTF-32 строки. Чтобы выразить 32-битные значения Unicode в строке, мы можем использовать форму \u****
, где ****
- четырехзначное шестнадцатеричное значение кодовой точки.
Если кодовая точка больше 4, мы будем использовать {}
для переноса цифр (\u{*****}
).
void main() { Runes heart = Runes('\u2665'); Runes laugh = Runes('\u{1f600}'); print(String.fromCharCodes(heart) + ' ' + String.fromCharCodes(laugh)); }
Вышеупомянутые отпечатки: '♥ 😀'
Рядом с указанными выше встроенными типами у нас есть типы enum и динамический.
Перечислимый тип может быть объявлен с помощью ключевого слова enum и позволяет нам определять набор постоянных значений безопасным для типов способом (обычно используется в операторах switch). У каждого значения есть метод получения index, который возвращает отсчитываемую от нуля позицию этого значения. values дает нам доступ ко всем значениям в перечислении.
enum Pet { cat, dog, bird, reptile, other } void main() { print('${Pet.values.length} pet types'); dynamic myPet = Pet.cat; switch(myPet) { case Pet.cat: print('meow'); break; case Pet.dog: print('woof'); break; case Pet.bird: print('tweet'); break; case Pet.reptile: print('ssSss'); break; case Pet.other: print(''); break; } }
Тип динамический используется, когда нам неизвестен (или не важен) тип объекта.
Оператор is может использоваться для проверки того, имеет ли динамический объект какой-либо тип (метод получения runtimeType дает нам доступ к фактическому типу).
Иногда тип динамический путают с объектом (который следует использовать, когда мы хотим указать, что все объекты приняты).
void main() { dynamic value = false; print(value.runtimeType); value = 'Dart'; if(value is String) { print(value.runtimeType); } }
Все эти встроенные типы являются частью языка программирования Dart и обеспечивают гибкость и возможности для ввода наших объектов.
В следующей части серии Fluttering Dart мы углубимся в функции, еще один фундаментальный принцип Dart, необходимый для создания надежных приложений Flutter.
Это все!