Flutter 套装 【高效的dart 代码标准】

352 阅读6分钟

MarkDown 格式乱码,可查看文稿 Dart 规范文档.pdf

代码风格指南

在 Dart 中标识符有三种类型。

  • UpperCamelCase 每个单词的首字母都大写,包含第一个单词。
  • lowerCamelCase 除了第一个字母始终是小写(即使是缩略词),每个单词的首字母都大写。
  • lowercase_with_underscores 只是用小写字母单词,即使是缩略词,并且单词之间使用 _ 连接。

请使用 UpperCamelCase 风格命名类型

Classes(类名)、 enums(枚举类型)、 typedefs(类型定义)、以及 type parameters(类型参数)应该把每个单词的首字母都大写(包含第一个单词),不使用分隔符。

class SliderMenu { ... }

class HttpRequest { ... }

typedef Predicate<T> = bool Function(T value);

如果注解类的构造函数是无参函数,则可以使用一个 lowerCamelCase 风格的常量来初始化这个注解。

const foo = Foo();

@foo
class C { ... }

请使用 UpperCamelCase 风格类型作为扩展名

与类型命名一样,extension 的名称也应大写每个单词的首字母(包括第一个单词),并且不使用分隔符。

 在lib、package、文件夹、源文件 中使用 lowercase_with_underscores 方式命名。

一些文件系统不区分大小写,所以很多项目要求文件名必须是小写字母。使用分隔符这种形式可以保证命名的可读性。使用下划线作为分隔符可确保名称仍然是有效的Dart标识符,如果语言后续支持符号导入,这将会起到非常大的帮助。

my_package

└─ lib

└─ file_system.dart

└─ slider_menu.dart

如果你 选择命名库,本准则给定了 如何 为库取名。如果需要,可以在文件中 省略 库指令。

如:

正确✅
import 'dart:math' as math;
import 'package:angular_components/angular_components.dart' as angular_components;
import 'package:js/js.dart' as js;
错误❌
import 'dart:math' as Math;
import 'package:angular_components/angular_components.dart' as AngularComponents;

请使用 lowerCamelCase 风格来命名其他的标识符

类成员、顶级定义、变量、参数以及命名参数等 除了第一个单词,每个单词首字母都应大写,并且不使用分隔符。

var count = 3;
HttpRequest httpRequest;
void align(bool clearItems) {
}

推荐 使用 lowerCamelCase 来命名常量

在新的代码中,使用 lowerCamelCase 来命名常量,包括枚举的值。

要 把 “dart:” 导入语句放到其他导入语句之前。

import 'dart:async';
import 'dart:html';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';

 把 “package:” 导入语句放到项目相关导入语句之前。

 把导出 (export) 语句作为一个单独的部分放到所有导入语句之后。

//例如
import 'src/error.dart';
import 'src/foo_bar.dart';

export 'src/error.dart';

使用Dart Format插件格式化代码,让代码看起来更友好。

格式化是一项繁琐的工作,尤其在重构过程中特别耗时。庆幸的是,你不必担心。我们提供了一个名为 dart format 的优秀的自动代码格式化程序,它可以为你完成格式化工作。 文档链接 , Dart 中任何官方的空格处理规则由 dart format* 生成*。

单行不超过 80 个字符

无论是定义类名、文件名、属性或者方法,最好不要超过80个字符。

可读性研究表明,长行的文字不易阅读,长行文字移动到下一行的开头时,眼睛需要移动更长的距离。这也是为什么报纸和杂志会使用多列样式的文字排版。

使用插值的形式来组合字符串和值。

避免在字符串插值中使用不必要的大括号

//推荐
'Hello, $name! You are ${year - birth} years old.';

// 不推荐
'Hello, ' + name + '! You are ' + (year - birth).toString() + ' y...';

集合

 尽可能的使用集合字面量。

Dart 有三种核心集合类型。List、Map 和 Set,这些类和大多数类一样,都有未命名的构造函数,但由于这些集合使用频率很高,Dart 有更好的内置语法来创建它们。

// 推荐
var points = <Point>[];
var addresses = <String, Address>{};
var counts = <int>{};

// 不推荐
var addresses = Map<String, Address>();
var counts = Set<int>();

集合字面量在 Dart 中特别强大,因为它们使您可以访问展开运算符以包含其他集合的内容,以及 if 和 for 在构建内容时执行控制流。

// 推荐
var arguments = [
...options,
command,
...?modeFlags,
for (var path in filePaths)
  if (path.endsWith('.dart')) path.replaceAll('.dart', '.js')
];

// 不推荐
var arguments = <String>[];
arguments.addAll(options);
arguments.add(command);
if (modeFlags != null) arguments.addAll(modeFlags);
arguments.addAll(filePaths
    .where((path) => path.endsWith('.dart'))
    .map((path) => path.replaceAll('.dart', '.js')));

不要 使用 List.from() 除非想修改结果的类型。

/// 推荐
// Creates a List<int>:
var iterable = [1, 2, 3];
// Prints "List<int>":
print(iterable.toList().runtimeType);

/// 不推荐
// Creates a List<int>:
var iterable = [1, 2, 3];

// Prints "List<dynamic>":
print(List.from(iterable).runtimeType);

// 如果想要更改类型,可以调用  List.from() :
var numbers = [1, 2.3, 4]; // List<num>.
numbers.removeAt(1); // Now it only contains integers.
var ints = List<int>.from(numbers);

 使用 whereType() 按类型过滤集合。

如果有更合适的方法,就不要使用cast(),因为会经过多次转换

// 不推荐
var objects = [1, 'a', 2, 'b', 3];
var ints = objects.where((e) => e is int).cast<int>();

// 推荐
var objects = [1, 'a', 2, 'b', 3];
var ints = objects.whereType<int>();

使用库规则

不要 导入 package 中 src 目录下的库

lib 下的 src 目录 被指定 为 package 自己实现的私有库。基于包维护者对版本的考虑,package 使用了这种约定。在不破坏 package 的情况下,维护者可以自由地对 src 目录下的代码进行修改。

这意味着,你如果导入了其中的私有库,按理论来讲,一个不破坏 package 的次版本就会影响到你的代码。

my_package └─ lib

└─ api.dart

test

└─ api_test.dart

不能按以下方式引用:

import 'package:my_package/api.dart';
import '../lib/api.dart';

应该使用下面的方式

import 'package:my_package/api.dart';

不要显式地将变量初始化为 null

例如下面这样是不可取的:

Item? bestItem = null;