Классы, перечисления, typedef и типовые параметры
class SliderMenu { ... }
class HttpRequest { ... }
typedef Predicate = bool Function<T>(T value);
Включая классы для метаданных аннотаций
class Foo {
const Foo([arg]);
}
@Foo(anArg)
class A { ... }
@Foo()
class B { ... }
library peg_parser.source_scanner;
import 'file_system.dart';
import 'slider_menu.dart';
Не рекомендуется следующий подход:
library pegparser.SourceScanner;
import 'file-system.dart';
import 'SliderMenu.dart';
import 'dart:math' as math;
import 'package:angular_components/angular_components'
as angular_components;
import 'package:js/js.dart' as js;
Не рекомендуется следующий подход:
import 'dart:math' as Math;
import 'package:angular_components/angular_components'
as angularComponents;
import 'package:js/js.dart' as JS;
var item;
HttpRequest httpRequest;
void align(bool clearItems) {
// ...
}
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');
class Dice {
static final numberGenerator = Random();
}
Не рекомендуется следующий подход:
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');
class Dice {
static final NUMBER_GENERATOR = Random();
}
```#### Не использовать префиксы
Поскольку Dart может сообщить вам тип объявления, область видимости, изменяемость и другие свойства, нет необходимости кодировать эти свойства в названия идентификаторов.
default_timeout
Не рекомендуется следующий подход:
kDefaultTimeout
### Сортировка
Чтобы поддерживать чистоту заголовков ваших файлов, у нас есть правила, которые указывают, что должно появиться в них. Каждая "часть" должна быть разделена пустыми строками.
#### Введение необходимых библиотек Dart до других импортов
import 'dart:async'; import 'dart:html';
import 'package:bar/bar.dart'; import 'package:foo/foo.dart';
#### Введение библиотек внутри пакета до относительных импортов
import 'package:bar/bar.dart'; import 'package:foo/foo.dart';
import 'util.dart';
#### Импорт сторонних пакетов должен происходить до других пакетов
import 'package:bar/bar.dart'; import 'package:foo/foo.dart';
import 'package:my_package/util.dart';
#### В отдельной секции после всех импортов укажите экспорт
import 'src/error.dart'; import 'src/foo_bar.dart';
export 'src/error.dart';
Не рекомендуется следующий подход:
import 'src/error.dart'; export 'src/error.dart'; import 'src/foo_bar.dart';
### Используйте фигурные скобки для всех конструкций управления потоком
Это позволяет избежать проблем с "висячими" else
if (isWeekDay) { print('Bike to work!'); } else { print('Go dancing or read a book!'); }
If an if-expression does not have an else-clause, and the if-expression and its body can fit on a single line, you can omit the curly braces. Otherwise, if the body of the if-expression spans more than one line, use curly braces:```
if (arg == null) return defaultValue;
if (overflowChars != other.overflowChars) {
return overflowChars < other.overflowChars;
}
Не рекомендуется следующий подход:
if (overflowChars != other.overflowChars)
return overflowChars < other.overflowChars;
Первое слово должно быть с большой буквы, если это не регистрозависимый идентификатор. Заканчивайте точкой (или "!" или "?"). Это касается всех комментариев: doc-комментариев, встроенных комментариев, даже TODOs. Даже если это фрагмент предложения.
greet(name) {
// Предполагаем, что у нас есть действительное имя.
print('Привет, $name!');
}
Не рекомендуется следующий подход:
greet(name) {
/* Предполагаем, что у нас есть действительное имя. */
print('Привет, $name!');
}
Используйте блочные комментарии (/* */) для временного комментирования участка кода, но используйте // для всех других комментариев.
Используйте /// для doc-комментариев для описания членов и типов.
Используйте doc-комментарии вместо обычных комментариев, чтобы dartdoc мог найти и сгенерировать документацию.
/// Количество символов в этом фрагменте при разбиении.
int get length => ...
```> Из-за исторических причин, Dart поддерживает два синтаксиса для doc-комментариев: // (стиль C#) и /** ... */ (стиль JavaDoc). Мы предпочитаем ///, так как он компактнее. /** и */ добавляют две пустые строки в многострочных doc-комментариях. В некоторых случаях синтаксис /// также проще читать, например, если doc-комментарий содержит список элементов с маркером *.### Рассмотрите написание документации для приватных APIДокументация для комментариев не предназначена только для внешних пользователей публичных API библиотеки. Они также помогают понять приватные члены, вызываемые из других частей библиотеки.
#### Начните документацию одним предложением
Начните свой комментарий документации кратким, ориентированным на пользователя описанием, заканчивающимся точкой.
```dart
/// Удаляет файл по [path] из файловой системы.
void delete(String path) {
...
}
Не рекомендуется следующий подход:
/// В зависимости от состояния файловой системы и прав пользователя,
/// некоторые операции могут быть возможны или невозможны. Если файл
/// по [path] отсутствует или недоступен, эта функция выбрасывает
/// соответственно [IOError] или [PermissionError]. В противном случае,
/// этот файл удаляется.
void delete(String path) {
...
}
После первого предложения добавьте пустую строку, чтобы разделить его от последующего текста.
/// Удаляет файл по [path].
///
/// Выбрасывает [IOError], если файл не был найден. Выбрасывает
/// [PermissionError], если файл присутствует, но не может быть удален.
void delete(String path) {
...
}
В Flutter Go импортируйте библиотеку из папки lib, указывая единую точку доступа, чтобы избежать множества ../../
.```
package:flutter_go/
### Использование строк
#### Соединение строк с помощью смежных строковых литералов
Если у вас есть два строковых литерала (не значения, а фактические ссылки на литералы), то использование оператора + для их соединения не требуется. Как в C и C++, просто расположите их рядом. Это хороший способ создания длинной строки, но не подходит для отдельных строк.
```dart
raiseAlarm(
'ERROR: Части космического корабля горят. Другие '
'части захвачены марсианами. Неясно, какие это.');
Не рекомендуется следующий подход:
raiseAlarm('ERROR: Части космического корабля горят. Другие ' +
'части захвачены марсианами. Неясно, какие это.');
'Привет, $name! Тебе ${year - birth} лет.';
'Привет, $name!'
'Надень самую необычную $decade\'s одежду.'
Не рекомендуется следующий подход:
'Привет, ' + name + '! Тебе ' + (year - birth).toString() + ' лет.';
Не рекомендуется использовать следующий синтаксис:
'Привет, ${name}!'
'Надень самую яркую ${decade}-ю одежду.'
Если вам нужно создать непостоянное множество или другие пользовательские типы множеств, используйте конструктор.
var points = [];
var addresses = {};
var lines = <Lines>[];
```Не рекомендуется использовать следующий синтаксис:
var points = List(); var addresses = Map();
#### Не используйте .length для проверки пустоты множества
if (lunchBox.isEmpty) return 'так голодно...'; if (words.isNotEmpty) return words.join(' ');
Не рекомендуется использовать следующий синтаксис:
if (lunchBox.length == 0) return 'так голодно...'; if (!words.isEmpty) return words.join(' ');
#### Рассмотрите использование встроенных методов для преобразования последовательностей
Если вам нужно создать новое множество на основе существующего, используйте методы .map(), .where() и другие удобные методы для итерируемых объектов.
var aquaticNames = animals .where((animal) => animal.isAquatic) .map((animal) => animal.name);
#### Избегайте использования Iterable.forEach() с функциональными литералами
В Dart для перебора последовательностей используется цикл.
for (var person in people) { ... }
Не рекомендуется использовать следующий синтаксис:
people.forEach((person) { ... });
#### Не используйте List.from(), если не планируете изменить тип результата
Для создания нового списка с теми же элементами есть два способа:
var copy1 = iterable.toList(); var copy2 = List.from(iterable);
Основное различие заключается в том, что первый способ сохраняет параметры типа оригинального объекта.
// Создает List: var iterable = [1, 2, 3];
// Выводит "List": print(iterable.toList().runtimeType);
// Создает List: var iterable = [1, 2, 3];
// Выводит "List": print(List.from(iterable).runtimeType);
#### Используйте = для разделения именованных параметров и их значений по умолчанию
Для указания значений по умолчанию параметров Dart позволяет использовать как ":" так и "=". Для согласованности с опциональными позиционными параметрами рекомендуется использовать "=".
```dart
void insert(Object item, {int at = 0}) { ... }
Не рекомендуется использовать следующий синтаксис:
void insert(Object item, {int at: 0}) { ... }
Если параметр является необязательным, но ему не задано значение по умолчанию, то язык автоматически использует null в качестве значения по умолчанию, поэтому явное указание не требуется.
void error([String message]) {
stderr.write(message ?? '\n');
}
Не рекомендуется следующий подход:
void error([String message = null]) {
stderr.write(message ?? '\n');
}
В Dart неявно инициализированные переменные или поля автоматически инициализируются значением null. Не следует явно присваивать null.
int _nextId;
class LazyId {
int _id;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
Не рекомендуется следующий подход:
int _nextId = null;
class LazyId {
int _id = null;
int get id {
if (_nextId == null) _nextId = 0;
if (_id == null) _id = _nextId++;
return _id;
}
}
Не рекомендуется следующий подход:
class Circle {
num radius;
num area;
num circumference;
Circle(num radius)
: radius = radius,
area = pi * radius * radius,
circumference = pi * 2.0 * radius;
}
Проблемы с данным подходом:
Рекомендуется следующий подход:
class Circle {
num radius;
Circle(this.radius);
num get area => pi * radius * radius;
num get circumference => pi * 2.0 * radius;
}
Не рекомендуется следующий подход:
class Box {
var _contents;
get contents => _contents;
set contents(value) {
_contents = value;
}
}
В особенности для StatelessWidget
Не рекомендуется следующий подход:
class Box {
var value;
void clear() {
this.update(null);
}
void update(value) {
this.value = value;
}
}
Рекомендуется следующий подход:
класс Box {
var value;
void clear() {
update(null);
}
void update(value) {
value = this.value;
}
}
class Point {
num x, y;
Point(num x, num y) {
this.x = x;
this.y = y;
}
}
Рекомендуется следующий подход:
class Point {
num x, y;
Point(this.x, this.y);
}
new
Dart 2 делает ключевое слово new
необязательным.
Рекомендуемый подход:
Widget build(BuildContext context) {
return Row(
children: [
RaisedButton(
child: Text('Increment'),
),
Text('Click!'),
],
);
}
Не рекомендуется следующий подход:
Widget build(BuildContext context) {
return new Row(
children: [
new RaisedButton(
child: new Text('Increment'),
),
new Text('Click!'),
],
);
}
async/await
вместо исходных futures
Синтаксис async/await
повышает читаемость и позволяет использовать все структуры управления потоком Dart в асинхронном коде.
Future<int> countActivePlayers(String teamName) async {
try {
var team = await downloadTeam(teamName);
if (team == null) return 0;
var players = await team.roster;
return players.where((player) => player.isActive).length;
} catch (e) {
log.error(e);
return 0;
}
}
Если можно исключить асинхронное выполнение без изменения поведения функции, то это следует сделать.
Future afterTwoThings(Future first, Future second) {
return Future.wait([first, second]);
}
Не рекомендуется следующий подход:
Future afterTwoThings(Future first, Future second) async {
return Future.wait([first, second]);
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )