Экскурсия по Dart
Простая программа на Dart
main() {
print('Привет мир');
}
Важнейшие понятия
Все, что вы можете поместить в переменную, есть объект, каждый объект
является экземпляром класса.
Dart является строго типизированным, аннотации типа опциональны, потому
что Dart может приводить типы.
Dart поддерживает generic types, как List<int> (список целых) или
List<dynamic>
Dart поддерживает глобальные функции, а также функции класа или объекта
( mixin ).
Dart поддерживает глобальные переменные, а также переменые класа или
объекта (статические и переменные экземпляра).
В отличии от Java, Dart не имеет ключевых слов public, protected и private.
Если переменная начинается с символа нижнее подчеркивание (_), то
переменная является приватной для класса или модуля.
Переменные
Примеры создания переменной и ее инициализации:
var name = 'Bob';
dynamic name = 'Bob';
String name = 'Bob';
Встроенные типы
Dart имеет поддержку для следующих типов:
numbers
strings
booleans
lists (arrays)
sets
maps
runes (для отображения символов Юникода в строке)
symbols
Numbers
В Dart числа бывают двух видов:
int
Целочисленные значения не более 64 бит, в зависимости от платформы.
На Dart VM значения могут быть от -2ˆ63 до 2ˆ(63 - 1).
Dart, скомпилированный для JavaScript, использует числа JavaScript,
допускающие значения от -2ˆ53 до 2ˆ(53 - 1).
double
64-бит (с двойной точностью) числа с плавающей точкой, как указано в стандарте
IEEE 754.
Strings
Строка Dart представляет собой последовательность кодовых единиц UTF-16.
Вы можете использовать одинарные или двойные кавычки для создания строки:
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It's easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";
Boolean
Для представления логических значений у Dart есть тип с именем bool.
Lists (array)
В Dart массивы являются объектами List, поэтому большинство людей просто
называют их списками.
var list = [1, 2, 3];
Sets
Set в Dart - это неупорядоченная коллекция уникальных значений.
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
Maps
Map - это объект, который связывает ключи и значения.
И ключи, и значения могут быть объектами любого типа.
Каждый ключ встречается только один раз, но вы можете использовать одно и то
же значение несколько раз.
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
var nobleGases = {
2: 'helium',
10: 'neon',
18: 'argon',
};
Runes
В Dart руны - это кодовые значки UTF-32 строки.
main() {
var clapping = 'u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'u2665 u{1f605} u{1f60e} u{1f47b} u{1f596} u{1f44d}');
print(new String.fromCharCodes(input));
}
Console
[55357, 56399]
[128079]
♥
Symbols
Объект Symbol представляет оператор или идентификатор, объявленный в
программе Dart. Они неоценимы для API, которые ссылаются на идентификаторы
по имени.
Чтобы получить символ для идентификатора, используйте символьный литерал
# , за которым следует идентификатор
#radix
#bar
Символьные литералы являются константами времени компиляции.
Functions
Dart - это настоящий объектно-ориентированный язык, поэтому даже функции
являются объектами и имеют тип Function.
Вот пример реализации функции:
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
или:
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
Cокращенный синтаксис:
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
Операторы
Dart использует те же операторы, с теми же приоритетами, что и C, Java и другие
подобные языки. Они будут вести себя так, как вы ожидаете.
Описание оператор
постфиксные операторы expr++ expr-- () [] . ?.
префиксные операторы -expr !expr ~expr ++expr --expr
мультипликативные операторы * / % ~/
аддитивные операторы + -
операторы сдвига << >> >>>
побитовый оператор AND &
побитовый оператор XOR ^
Описание оператор
побитовый оператор OR |
операторы сравнения >= > <= < as is is!
equaоператоры равенства == !=
логический оператор AND &&
логический оператор OR ||
оператор if null ??
условные операторы expr1 ? expr2 : expr3
каскадный оператор ..
операторы присваивания = *= /= += -= &= ^= etc.
Каскадный оператор
Каскады ( .. ) позволяют выполнять последовательность операций над одним и
тем же объектом. В дополнение к вызовам функций вы также можете получить
доступ к полям этого же объекта.
querySelector('#confirm') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
Операторы управления потоком
Вы можете контролировать поток выполнения своего кода в Dart, используя
ключевые слова:
if и else
цикл for
циклы while и do-while
break и continue
switch и case
assert
Исключения
Код Dart может генерировать и ловить исключения. Исключением являются
ошибки, указывающие на то, что произошло что-то неожиданное.
Ключевые слова:
try
catch
finally
throw
Классы
Dart является объектно-ориентированным языком, и каждое значение, которым
мы манипулируем в программе на Dart, является объектом.
class Person{
String name;
void display(){
print("Name: $name");
}
}
class Employee extends Person{
}
Именованные конструкторы
Как большинство динамических языков, Dart не поддерживает перегрузку.
Поэтому Dart позволяет использовать именованные конструкторы.
class Point {
num x, y;
Point(this.x, this.y);
Point.zero() : x = 0, y = 0;
}
Поля, геттеры и сеттеры
Для работы со свойствами Dart использует стандартный синтаксис вида
object.someProperty. В Dart вы можете определить методы, которые будут
выглядеть, как обращение к полю класса, но при этом выполнять произвольный
код. Такие методы называются геттерами и сеттерами:
class Rectangle {
num left, top, width, height;
num get right() => left + width;
set right(num value) => left = value - width;
num get bottom() => top + height;
set bottom(num value) => top = value - height;
Rectangle(this.left, this.top, this.width, this.height);
}
Абстрактные классы
Используйте модификатор abstract для определения абстрактного класса - класс,
который не может быть создан. Абстрактные классы полезны для определения
интерфейсов, часто с некоторой реализацией.
Абстрактные классы часто имеют абстрактные методы. Вот пример объявления
абстрактного класса, который имеет абстрактный метод:
// This class is declared abstract and thus
// can't be instantiated.
abstract class AbstractContainer {
// Define constructors, fields, methods...
void updateChildren(); // Abstract method.
}
Неявные интерфейсы
Каждый класс в Dart неявно определяет интерфейс, содержащий все поля и
методы экземпляра класса и любые интерфейсы, которые он реализует. То есть
класс в Dart одновременно выступает в роли интерфейса, и другой класс может
реализовать данный интерфейс.
class Person{
String name;
Person(this.name);
void display(){
print("Name: $name");
}
}
class Employee implements Person{
String name; // реализация поля name
// реализация метода display
void display(){
print("Employee name: $name");
}
}
Наследовоание класса
Наследование является одним из ключевых моментов объектно-
ориентированного программирования, позволяя передавать одним классам
функционал других. В языке Dart наследование реализуется с помощью
ключевого слова extends (как в Java):
class Television {
void turnOn() {
_illuminateDisplay();
_activateIrSensor();
}
}
class SmartTelevision extends Television {
void turnOn() {
super.turnOn();
_bootNetworkInterface();
_initializeMemory();
_upgradeApps();
}
}
Примеси
Примесь (англ. mix in) — элемент языка программирования (обычно класс или
модуль), реализующий какое-либо четко выделенное поведение. Используется
для уточнения поведения других классов, не предназначен для порождения
самостоятельно используемых объектов.
Пример
class Transport {
void move() {
print("move");
}
}
mixin Car {
void drive() {
print("drive");
}
}
mixin Airplane {
void fly() {
print("fly");
}
}
class CarPlane extends Transport with Car, Airplane {
}
Перечисляемые типы
Enum представляют собой особый вид класса, используемый для представления
фиксированного числа постоянных значений.
Использование перечислений
Объявите перечислимый тип, используя ключевое слово enum:
enum Color { red, green, blue }
Generics
Generics или обобщения позволяют добавить программе гибкости и уйти от
жесткой привязки к определенным типам.
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
Поддержка асинхронности
Код в Dart работает в одном потоке выполнения. Если код занят долгими
вычислениями или ожидает операцию I/O, то вся программа приостанавливается.
Асинхронные операции позволяют вашей программе завершить другие задачи в
ожидании завершения операции. Dart использует futures для представления
результатов асинхронных операций. Для работы с futures можно также
использовать async и await или Future API .
Async — await
Ключевые слова async и await являются частью поддержки асинхронности в
Dart. Они позволяют писать асинхронный код, который выглядит как синхронный
код и не использует Future API . Асинхронная функция — это функция, перед
телом которой находится ключевое слово async . Ключевое слово await
работает только в асинхронных функциях.
Future<String> lookUpVersion() async => '1.0.0';
Future main() async {
print('In main: version is ${await lookUpVersion()}');
}
Future API
До того, как async и await были добавлены в Dart 1.9, вы должны были
использовать Future API. Вы и сейчас можете встретить использование Future API
в старом коде и в коде, который нуждается в большей функциональности, чем
async–await может предложить.
Чтобы написать асинхронный код с помощью Future API, используйте метод then()
для регистрации обратного вызова. Этот обратный вызов сработает, когда future
завершится.
Future<String> lookUpVersion() => Future.value('1.0.0');
void main() {
lookUpVersion().then((String version) {
print('In main: version is $version');
});
}
Streams (потоки)
Stream в Dart - это последовательность асинхронных событий. Stream сообщает
вам, что есть событие и когда оно будет готово.
Существует два типа потоков:
Потоки-подписки (single subscription)
Широковещательные (broadcast).
Потоки-подписки (single subscription)
Потоки-подписки - это тип потока который содержит последовательность
событий, которые являются частями большего целого. События должны быть
доставлены в правильном порядке без пропуска любого из них. Это тип потока,
который вы получаете при чтении файла или получении веб-запроса. Такой
поток можно слушать только один раз.
Пример
// Для создания потока используем StreamController
var controller = new StreamController<String>();
// Прослушиваем поток
StreamSubscription subscription = controller.stream.listen((item) => print(item));
controller.add("Item1");
controller.add("Item2");
controller.add("Item3");
// Это сделано для того, чтобы среда тестирования не убила этот процесс
// до того, как все объекты из Stream были обработаны
await Future.delayed(Duration(milliseconds: 500));
subscription.cancel;
Широковещательные (broadcast)
Широковещательные потоки - тип потока предназначен для отдельных
сообщений, которые могут обрабатываться по одному. Вы можете начать слушать
такой поток в любое время, и вы получите события, произошедшие во время
прослушивания. Поток могут слушать несколько слушателей. Вы можете снова
начать слушать события потока после отмены предыдущей подписки.
Пример
// Для создания потока используем StreamController
var controller = new StreamController.broadcast();
// Прослушиваем поток
StreamSubscription subscription = controller.stream.listen((item) => print(item));
controller.add("Item1");
await Future.delayed(Duration(milliseconds: 500));
controller.add("Item2");
StreamSubscription subscription1 = controller.stream.listen((item) => print(item));
await Future.delayed(Duration(milliseconds: 500));
controller.add("Item3");
// Это сделано для того, чтобы среда тестирования не убила этот процесс
// до того, как все объекты из Stream были обработаны
await Future.delayed(Duration(milliseconds: 500));
subscription.cancel;
subscription1.cancel;
Спасибо за внимание!

Погружение в Dart

  • 1.
  • 2.
    Простая программа наDart main() { print('Привет мир'); }
  • 3.
    Важнейшие понятия Все, чтовы можете поместить в переменную, есть объект, каждый объект является экземпляром класса. Dart является строго типизированным, аннотации типа опциональны, потому что Dart может приводить типы. Dart поддерживает generic types, как List<int> (список целых) или List<dynamic> Dart поддерживает глобальные функции, а также функции класа или объекта ( mixin ). Dart поддерживает глобальные переменные, а также переменые класа или объекта (статические и переменные экземпляра). В отличии от Java, Dart не имеет ключевых слов public, protected и private. Если переменная начинается с символа нижнее подчеркивание (_), то переменная является приватной для класса или модуля.
  • 4.
    Переменные Примеры создания переменнойи ее инициализации: var name = 'Bob'; dynamic name = 'Bob'; String name = 'Bob';
  • 5.
    Встроенные типы Dart имеетподдержку для следующих типов: numbers strings booleans lists (arrays) sets maps runes (для отображения символов Юникода в строке) symbols
  • 6.
    Numbers В Dart числабывают двух видов: int Целочисленные значения не более 64 бит, в зависимости от платформы. На Dart VM значения могут быть от -2ˆ63 до 2ˆ(63 - 1). Dart, скомпилированный для JavaScript, использует числа JavaScript, допускающие значения от -2ˆ53 до 2ˆ(53 - 1). double 64-бит (с двойной точностью) числа с плавающей точкой, как указано в стандарте IEEE 754.
  • 7.
    Strings Строка Dart представляетсобой последовательность кодовых единиц UTF-16. Вы можете использовать одинарные или двойные кавычки для создания строки: var s1 = 'Single quotes work well for string literals.'; var s2 = "Double quotes work just as well."; var s3 = 'It's easy to escape the string delimiter.'; var s4 = "It's even easier to use the other delimiter.";
  • 8.
    Boolean Для представления логическихзначений у Dart есть тип с именем bool.
  • 9.
    Lists (array) В Dartмассивы являются объектами List, поэтому большинство людей просто называют их списками. var list = [1, 2, 3];
  • 10.
    Sets Set в Dart- это неупорядоченная коллекция уникальных значений. var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
  • 11.
    Maps Map - этообъект, который связывает ключи и значения. И ключи, и значения могут быть объектами любого типа. Каждый ключ встречается только один раз, но вы можете использовать одно и то же значение несколько раз. var gifts = { // Key: Value 'first': 'partridge', 'second': 'turtledoves', 'fifth': 'golden rings' }; var nobleGases = { 2: 'helium', 10: 'neon', 18: 'argon', };
  • 12.
    Runes В Dart руны- это кодовые значки UTF-32 строки. main() { var clapping = 'u{1f44f}'; print(clapping); print(clapping.codeUnits); print(clapping.runes.toList()); Runes input = new Runes( 'u2665 u{1f605} u{1f60e} u{1f47b} u{1f596} u{1f44d}'); print(new String.fromCharCodes(input)); } Console [55357, 56399] [128079] ♥
  • 13.
    Symbols Объект Symbol представляетоператор или идентификатор, объявленный в программе Dart. Они неоценимы для API, которые ссылаются на идентификаторы по имени. Чтобы получить символ для идентификатора, используйте символьный литерал # , за которым следует идентификатор #radix #bar Символьные литералы являются константами времени компиляции.
  • 14.
    Functions Dart - этонастоящий объектно-ориентированный язык, поэтому даже функции являются объектами и имеют тип Function. Вот пример реализации функции: bool isNoble(int atomicNumber) { return _nobleGases[atomicNumber] != null; } или: isNoble(atomicNumber) { return _nobleGases[atomicNumber] != null; } Cокращенный синтаксис: bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
  • 15.
    Операторы Dart использует теже операторы, с теми же приоритетами, что и C, Java и другие подобные языки. Они будут вести себя так, как вы ожидаете.
  • 16.
    Описание оператор постфиксные операторыexpr++ expr-- () [] . ?. префиксные операторы -expr !expr ~expr ++expr --expr мультипликативные операторы * / % ~/ аддитивные операторы + - операторы сдвига << >> >>> побитовый оператор AND & побитовый оператор XOR ^
  • 17.
    Описание оператор побитовый операторOR | операторы сравнения >= > <= < as is is! equaоператоры равенства == != логический оператор AND && логический оператор OR || оператор if null ?? условные операторы expr1 ? expr2 : expr3 каскадный оператор .. операторы присваивания = *= /= += -= &= ^= etc.
  • 18.
    Каскадный оператор Каскады (.. ) позволяют выполнять последовательность операций над одним и тем же объектом. В дополнение к вызовам функций вы также можете получить доступ к полям этого же объекта. querySelector('#confirm') // Get an object. ..text = 'Confirm' // Use its members. ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!'));
  • 19.
    Операторы управления потоком Выможете контролировать поток выполнения своего кода в Dart, используя ключевые слова: if и else цикл for циклы while и do-while break и continue switch и case assert
  • 20.
    Исключения Код Dart можетгенерировать и ловить исключения. Исключением являются ошибки, указывающие на то, что произошло что-то неожиданное. Ключевые слова: try catch finally throw
  • 21.
    Классы Dart является объектно-ориентированнымязыком, и каждое значение, которым мы манипулируем в программе на Dart, является объектом. class Person{ String name; void display(){ print("Name: $name"); } } class Employee extends Person{ }
  • 22.
    Именованные конструкторы Как большинстводинамических языков, Dart не поддерживает перегрузку. Поэтому Dart позволяет использовать именованные конструкторы. class Point { num x, y; Point(this.x, this.y); Point.zero() : x = 0, y = 0; }
  • 23.
    Поля, геттеры исеттеры Для работы со свойствами Dart использует стандартный синтаксис вида object.someProperty. В Dart вы можете определить методы, которые будут выглядеть, как обращение к полю класса, но при этом выполнять произвольный код. Такие методы называются геттерами и сеттерами: class Rectangle { num left, top, width, height; num get right() => left + width; set right(num value) => left = value - width; num get bottom() => top + height; set bottom(num value) => top = value - height; Rectangle(this.left, this.top, this.width, this.height); }
  • 24.
    Абстрактные классы Используйте модификаторabstract для определения абстрактного класса - класс, который не может быть создан. Абстрактные классы полезны для определения интерфейсов, часто с некоторой реализацией. Абстрактные классы часто имеют абстрактные методы. Вот пример объявления абстрактного класса, который имеет абстрактный метод: // This class is declared abstract and thus // can't be instantiated. abstract class AbstractContainer { // Define constructors, fields, methods... void updateChildren(); // Abstract method. }
  • 25.
    Неявные интерфейсы Каждый классв Dart неявно определяет интерфейс, содержащий все поля и методы экземпляра класса и любые интерфейсы, которые он реализует. То есть класс в Dart одновременно выступает в роли интерфейса, и другой класс может реализовать данный интерфейс. class Person{ String name; Person(this.name); void display(){ print("Name: $name"); } } class Employee implements Person{ String name; // реализация поля name // реализация метода display void display(){ print("Employee name: $name"); } }
  • 26.
    Наследовоание класса Наследование являетсяодним из ключевых моментов объектно- ориентированного программирования, позволяя передавать одним классам функционал других. В языке Dart наследование реализуется с помощью ключевого слова extends (как в Java): class Television { void turnOn() { _illuminateDisplay(); _activateIrSensor(); } } class SmartTelevision extends Television { void turnOn() { super.turnOn(); _bootNetworkInterface(); _initializeMemory(); _upgradeApps(); } }
  • 27.
    Примеси Примесь (англ. mixin) — элемент языка программирования (обычно класс или модуль), реализующий какое-либо четко выделенное поведение. Используется для уточнения поведения других классов, не предназначен для порождения самостоятельно используемых объектов.
  • 28.
    Пример class Transport { voidmove() { print("move"); } } mixin Car { void drive() { print("drive"); } } mixin Airplane { void fly() { print("fly"); } } class CarPlane extends Transport with Car, Airplane { }
  • 29.
    Перечисляемые типы Enum представляютсобой особый вид класса, используемый для представления фиксированного числа постоянных значений. Использование перечислений Объявите перечислимый тип, используя ключевое слово enum: enum Color { red, green, blue }
  • 30.
    Generics Generics или обобщенияпозволяют добавить программе гибкости и уйти от жесткой привязки к определенным типам. abstract class Cache<T> { T getByKey(String key); void setByKey(String key, T value); }
  • 31.
    Поддержка асинхронности Код вDart работает в одном потоке выполнения. Если код занят долгими вычислениями или ожидает операцию I/O, то вся программа приостанавливается. Асинхронные операции позволяют вашей программе завершить другие задачи в ожидании завершения операции. Dart использует futures для представления результатов асинхронных операций. Для работы с futures можно также использовать async и await или Future API .
  • 32.
    Async — await Ключевыеслова async и await являются частью поддержки асинхронности в Dart. Они позволяют писать асинхронный код, который выглядит как синхронный код и не использует Future API . Асинхронная функция — это функция, перед телом которой находится ключевое слово async . Ключевое слово await работает только в асинхронных функциях. Future<String> lookUpVersion() async => '1.0.0'; Future main() async { print('In main: version is ${await lookUpVersion()}'); }
  • 33.
    Future API До того,как async и await были добавлены в Dart 1.9, вы должны были использовать Future API. Вы и сейчас можете встретить использование Future API в старом коде и в коде, который нуждается в большей функциональности, чем async–await может предложить. Чтобы написать асинхронный код с помощью Future API, используйте метод then() для регистрации обратного вызова. Этот обратный вызов сработает, когда future завершится. Future<String> lookUpVersion() => Future.value('1.0.0'); void main() { lookUpVersion().then((String version) { print('In main: version is $version'); }); }
  • 34.
    Streams (потоки) Stream вDart - это последовательность асинхронных событий. Stream сообщает вам, что есть событие и когда оно будет готово. Существует два типа потоков: Потоки-подписки (single subscription) Широковещательные (broadcast).
  • 35.
    Потоки-подписки (single subscription) Потоки-подписки- это тип потока который содержит последовательность событий, которые являются частями большего целого. События должны быть доставлены в правильном порядке без пропуска любого из них. Это тип потока, который вы получаете при чтении файла или получении веб-запроса. Такой поток можно слушать только один раз.
  • 36.
    Пример // Для созданияпотока используем StreamController var controller = new StreamController<String>(); // Прослушиваем поток StreamSubscription subscription = controller.stream.listen((item) => print(item)); controller.add("Item1"); controller.add("Item2"); controller.add("Item3"); // Это сделано для того, чтобы среда тестирования не убила этот процесс // до того, как все объекты из Stream были обработаны await Future.delayed(Duration(milliseconds: 500)); subscription.cancel;
  • 37.
    Широковещательные (broadcast) Широковещательные потоки- тип потока предназначен для отдельных сообщений, которые могут обрабатываться по одному. Вы можете начать слушать такой поток в любое время, и вы получите события, произошедшие во время прослушивания. Поток могут слушать несколько слушателей. Вы можете снова начать слушать события потока после отмены предыдущей подписки.
  • 38.
    Пример // Для созданияпотока используем StreamController var controller = new StreamController.broadcast(); // Прослушиваем поток StreamSubscription subscription = controller.stream.listen((item) => print(item)); controller.add("Item1"); await Future.delayed(Duration(milliseconds: 500)); controller.add("Item2"); StreamSubscription subscription1 = controller.stream.listen((item) => print(item)); await Future.delayed(Duration(milliseconds: 500)); controller.add("Item3"); // Это сделано для того, чтобы среда тестирования не убила этот процесс // до того, как все объекты из Stream были обработаны await Future.delayed(Duration(milliseconds: 500)); subscription.cancel; subscription1.cancel;
  • 39.