1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/jianxia84-flutter-go

Клонировать/Скачать
Flutter_Go 代码开发规范.md 21 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 06.06.2025 08:36 fdb5e74

Правила написания кода для Flutter Go 0.1.0

Стиль кода

Три типа идентификаторов

Верблюжий регистр

Классы, перечисления, 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-комментариев для описания членов и типов.

Используйте 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

Импорт библиотеки

В 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

Если параметр является необязательным, но ему не задано значение по умолчанию, то язык автоматически использует null в качестве значения по умолчанию, поэтому явное указание не требуется.

void error([String message]) {
  stderr.write(message ?? '\n');
}

Не рекомендуется следующий подход:

void error([String message = null]) {
  stderr.write(message ?? '\n');
}

Переменные

Не явно инициализируйте переменные значением null

В 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;
    }
  }

Приоритетное использование final для создания только для чтения свойств

В особенности для StatelessWidget

Не используйте this, если это не требуется

Не рекомендуется следующий подход:

  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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/jianxia84-flutter-go.git
git@api.gitlife.ru:oschina-mirror/jianxia84-flutter-go.git
oschina-mirror
jianxia84-flutter-go
jianxia84-flutter-go
master