Code前端首页关于Code前端联系我们

学习Flutter开发需要了解的Dart编码标准

terry 2年前 (2023-09-23) 阅读数 65 #移动小程序

编码习惯因人而异,没有最好的解决方案。

如果你独自开发,当然不需要担心这些问题,但是如果你需要向别人展示你的代码或者与别人协作开发,那么编码标准就非常有必要了。

下面我们从官方文档中选取一些最基本、最典型、最常出现的情况作为规范。

✅ 代表正向方式,❌ 负向方式

样式规范

名称

DO:类、枚举、类型定义,不需要使用大写 使用注释时也应该如此

✅

class Foo {
  const Foo([arg]);
}

@Foo(anArg)
class A { ... }

@Foo()
class B { ... }
复制代码

De 在注释类的构造函数时,您可能需要创建一个以小写字母开头的注释变量

✅

const foo = Foo();

@foo
class C { ... }
复制代码

DO:库、包、目录和 dart 文件的名称应小写 添加下划线

✅

library peg_parser.source_scanner;

import 'file_system.dart';
import 'slider_menu.dart';
复制代码
❌

library pegparser.SourceScanner;

import 'file-system.dart';
import 'SliderMenu.dart';
复制代码

DO : 使用 as 转换的名称必须有小写下划线

✅

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;
复制代码

DO: 变量名、方法名、参数名都应为小写命名法

✅

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();
}

复制代码

消除大括号 DO : 如果只有一个 if 语句而没有其他语句,则可以如果在一行中显示良好,则不需要大括号

✅

if (arg == null) return defaultValue;
复制代码

但如果很难在一行中显示,则应使用大括号:

✅

if (overflowChars != other.overflowChars) {
  return overflowChars < other.overflowChars;
}
复制代码
❌

if (overflowChars != other.overflowChars)
  return overflowChars < other.overflowChars;
复制代码

文档规范

DO:我们建议使用 /// 代替改为dart评论中的//

✅

/// The number of characters in this chunk when unsplit.
int get length => ...
复制代码
❌

// The number of characters in this chunk when unsplit.
int get length => ...
复制代码

,官方表示这是历史原因,他们觉得在某些情况下似乎更方便阅读。 。

DO:对文档的注释必须以简洁的句子开头。

✅

/// Deletes the file at [path] from the file system.
void delete(String path) {
  ...
}
复制代码
❌

/// Depending on the state of the file system and the user's permissions,
/// certain operations may or may not be possible. If there is no file at
/// [path] or it can't be accessed, this function throws either [IOError]
/// or [PermissionError], respectively. Otherwise, this deletes the file.
void delete(String path) {
  ...
}
复制代码

DO:将评论的第一句与其余内容分开。 使用规范

依赖项

首选:我们建议使用相对路径导入依赖项。 api.dart

❌

var objects = [1, "a", 2, "b", 3];
var ints = objects.where((e) => e is int);
复制代码
❌

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>();
复制代码

utils。 dart任务

DO:使用 ??转换空值

在 Dart 中,运算符 ?? 表示如果某个值为空,系统会分配一个值 ? ? 以下数据

❌

if (optionalThing?.isEnabled) {
  print("Have enabled thing.");
}
复制代码

如果可选Thing为空,则会出现空异常。

在这里解释一下。运算符 ?. 对应于空操作。仅当 OptionalThing 不为空时,才会调用参数 isEnabled。当 OptionalThing 如果为空时,默认返回 null。如果在 if 语句中使用则不行 DO:直接使用 Enter 分隔字符串

✅

raiseAlarm(
    'ERROR: Parts of the spaceship are on fire. Other '
    'parts are overrun by martians. Unclear which are which.');
复制代码
❌

raiseAlarm('ERROR: Parts of the spaceship are on fire. Other ' +
    'parts are overrun by martians. Unclear which are which.');
复制代码

PREFER:使用 ${} 连接字符串和变量值方法:[]List();空 HashMap 共有三种方法:{}Map()Map()

✅

raiseAlarm(
    'ERROR: Parts of the spaceship are on fire. Other '
    'parts are overrun by martians. Unclear which are which.');
复制代码
❌

raiseAlarm('ERROR: Parts of the spaceship are on fire. Other ' +
    'parts are overrun by martians. Unclear which are which.');
复制代码

LMap() 始终使用如果要创建不可扩展列表或其他自定义集合类型,请使用构造函数。

DO:尽可能使用简单文字来创建集合

✅

var points = [];
var addresses = {};
复制代码
❌

var points = List();
var addresses = Map();
复制代码

如果要指定类型

✅

var points = <Point>[];
var addresses = <String, Address>{};
复制代码
❌

var points = List<Point>();
var addresses = Map<String, Address>();
复制代码

DO:如果集合为空,请勿使用 .length。

✅

if (lunchBox.isEmpty) return 'so hungry...';
if (words.isNotEmpty) return words.join(' ');
复制代码
❌

if (lunchBox.length == 0) return 'so hungry...';
if (!words.isEmpty) return words.join(' ');
复制代码

考虑:考虑使用高阶方法来转换数组

var aquaticNames = animals
    .where((animal) => animal.isAquatic)
    .map((animal) => animal.name);
复制代码

避免:避免将 Iterable.forEach() 与函数文字一起使用

forEach() 函数在 JavaScript 中广泛使用,即内置的 for-in循环并不能达到你通常想要的效果。在 Dart 中,如果要迭代序列,惯用的方法是使用循环。

✅

for (var person in people) {
  ...
}
复制代码
❌

people.forEach((person) {
  ...
});
复制代码

不要:不要使用List.from(),除非您打算更改结果的类型。 () 和 Iterable .toList()

✅

// 创建一个List<int>:
var iterable = [1, 2, 3];

// 输出"List<int>":
print(iterable.toList().runtimeType);
复制代码
❌

// 创建一个List<int>:
var iterable = [1, 2, 3];

// 输出"List<dynamic>":
print(List.from(iterable).runtimeType);
复制代码

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

❌

var objects = [1, "a", 2, "b", 3];
var ints = objects.where((e) => e is int);
复制代码
❌

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>();
复制代码

参数

DO:使用 = 设置参数默认值 不要:不要更改参数的默认值为零

✅

void error([String message]) {
  stderr.write(message ?? '\n');
}
复制代码
❌

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

变量

AVOID:避免存储可计算值​​

❌

class Circle {
  num _radius;
  num get radius => _radius;
  set radius(num value) {
    _radius = value;
    _recalculate();
  }

  num _area;
  num get area => _area;

  num _circumference;
  num get circumference => _circumference;

  Circle(this._radius) {
    _recalculate();
  }

  void _recalculate() {
    _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;
}
复制代码

成员 T不要编写不必要的 getter 和 setter

✅

class Box {
  var contents;
}
复制代码
❌

class Box {
  var _contents;
  get contents => _contents;
  set contents(value) {
    _contents = value;
  }
}
复制代码

构造函数

DO :尽可能多地使用简单的初始化表单

❌

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);
}
复制代码

ne:请勿使用在新的dart

✅

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!'),
    ],
  );
}
复制代码

ne中创建新对象:请勿使用冗余cont修改对象

✅

const primaryColors = [
  Color("red", [255, 0, 0]),
  Color("green", [0, 255, 0]),
  Color("blue", [0, 0, 255]),
];
复制代码
❌

const primaryColors = const [
  const Color("red", const [255, 0, 0]),
  const Color("green", const [0, 255, 0]),
  const Color("blue", const [0, 0, 255]),
];
复制代码

异常处理 re♼ row:使用♼异常

❌

try {
  somethingRisky();
} catch (e) {
  if (!canHandle(e)) throw e;
  handle(e);
}
复制代码
✅

try {
  somethingRisky();
} catch (e) {
  if (!canHandle(e)) rethrow;
  handle(e);
}
复制代码

设计规范

AVOID:避免方法返回 this 来实现流式调用 AVOID:避免 FutureOr 的返回类型

✅

Future<int> triple(FutureOr<int> value) async => (await value) * 3;
复制代码
❌

FutureOr<int> triple(FutureOr<int> value) {
  if (value is int) return value * 3;
  return (value as Future<int>).then((v) => v * 3);
}
复制代码

AVOID:避免直接输入使用它作为参数的布尔值'T:不要用自定义运算符方法进行判断==

✅

class Person {
  final String name;
  // ···
  bool operator ==(other) => other is Person && name == other.name;

  int get hashCode => name.hashCode;
}
复制代码
❌

class Person {
  final String name;
  // ···
  bool operator ==(other) => other != null && ...
}

作者:Android家伙链接:https://juejin.im/post/5d43a466fe15afd156d15 来源:掘金
版权归作者所有。商业转载请联系作者获得许可。非商业转载请注明来源。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门