Порхающий дротик

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.



Это все!