命名规范
遵循Dart的官方风格指南Dart官方风格指南,确保代码与社区推荐的格式保持一致。
注释与文档
- 使用三斜杠(
///)编写文档注释来描述公共 API 的功能、用法和约束。 - 对于复杂的逻辑和算法,使用双斜杠(
//)添加行内注释,解释代码的目的和实现方式。 - 保持注释简洁明了,并及时更新以保持与代码同步。
class TestClass {
/// 用户名
String? username;
/// 邮箱
String? email;
/// id
int? id;
/// 年龄
int _age = 0;
/// 获取年龄
///
/// 返回值:年龄
int get age => _age;
/// 设置年龄
///
/// [value] 要设置的年龄值
set age(int value) {
if (value < 0) {
throw ArgumentError('age 不能为负数');
}
_age = value;
}
/// 创建TestClass对象
///
/// [username] 用户名
/// [email] 邮箱
/// [id] id
TestClass(this.username, this.email, this.id);
/// 将对象转换为包含属性键值对的 Map。
///
/// 返回值:包含属性键值对的 Map。
Map<String, dynamic> toMap() {
return {
"username": username ?? "",
"email": email ?? "",
"id": id ?? 0,
};
}
/// 删除[路径]处的文件。
///
/// [path] 文件路径
/// 如果找不到文件,则抛出[IOError]。抛出一个
/// [PermissionError],如果文件存在但无法删除
void delete(String path) {}
/// 计算两个整数的和。
///
/// [a]:第一个整数
/// [b]:第二个整数
///
/// 返回值:两个整数的和
int calculateSum(int a, int b) {
return a + b;
}
}
布局代码规范
// 错误
// 未用const修饰, 逗号换行
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("test"),
),
extendBody: true,
body: Column(children: [
Spacer(),
Container(
margin: EdgeInsets.all(10),
child: Center(child: TextField()),
),
Spacer()
]));
}
// 正确
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("test"),
),
extendBody: true,
body: Column(
children: [
const Spacer(),
Container(
margin: const EdgeInsets.all(10),
child: const Center(
child: TextField(),
),
),
const Spacer(),
],
),
);
}
可选值处理
String? optionalValue;
// 错误
// 未进行判空处理
if (optionalValue!.isNotEmpty) {
print(optionalValue.length);
}
// 正确
if (optionalValue != null && optionalValue.isNotEmpty) {
print(optionalValue.length);
}
异常错误处理
- 使用
assert函数检查开发期间的错误条件。 - 使用
try-catch语句处理可能引发异常的代码,并使用finally子句清理资源。 - 在捕获异常时,通过日志记录或显示错误信息以便进行调试。
void divide(int dividend, int divisor) {
assert(divisor != 0, '除数不能为零');
try {
// 执行除法操作
double result = dividend / divisor;
print('结果:$result');
} catch (e) {
print('发生异常:$e');
} finally {
// 清理操作
print('执行清理操作');
}
}
void test() {
try {
// 可能抛出异常的代码
} on ExceptionType1 catch (e) {
// 处理 ExceptionType1 类型的异常
} on ExceptionType2 catch (e) {
// 处理 ExceptionType2 类型的异常
} catch (e) {
// 处理其他类型的异常
}
}
对于可能导致异步操作的函数,使用async和await关键字进行异步编程,并使用try-catch语句捕获和处理可能的异常
Future<void> fetchData() async {
try {
// 异步操作的代码逻辑
final response = await http.get('https://api.example.com/data');
// 处理响应数据
} catch (e) {
// 异常处理逻辑
print('发生异常:$e');
}
}
后端返回数据处理
- 不要相信后端返回的数据
- 不要相信后端返回的数据
- 不要相信后端返回的数据
- 后端返回的JSON数据必须转换成模型
// 错误
// 字段类型可能为空,类型可能不匹配,会引发异常
void test() async {
Map map = await fetchData();
String name = map["name"];
int age = map["age"];
int id = map["id"];
}
// 正确
void test() async {
Map map = await fetchData();
final model = Model.fromMap(map);
print(model.name);
print(model.age);
print(model.id);
}
class Model {
String? name;
int? age;
int? id;
Model.fromMap(Map map) {
name = _parseValue<String>(map["name"]);
age = _parseValue<int>(map["age"]);
id = _parseValue<int>(map["id"]);
}
T? _parseValue<T>(dynamic value) {
if (value is T) {
return value;
}
return null;
}
}
三木运算符使用
在 Dart 中,三木运算符 (ternary operator) 可以用于简化代码并减少 if-else 语句的使用。它的形式为 condition ? expression_if_true : expression_if_false。
使用规范
- 三木运算符的主要目的是减少代码量,并使代码更紧凑。因此,在选择使用时,考虑是否可以替代
if-else语句以提高代码的简洁性 - 过度使用三木运算符可能导致代码难以阅读。请避免在一个表达式中使用多个三木运算符,以确保代码可读性
// 错误
void test() {
int a = 10;
int b = 20;
int c = 30;
final status = a == 1 ? 6 : b == 2 ? 3 : c == 30 ? 2 : 40;
}
// 正确
void test() {
int a = 10;
int b = 20;
int c = 30;
var status = 40;
if (a == 1) {
status = 6;
} else if (b == 2) {
status = 3;
} else if (c == 30) {
status = 2;
}
}