第一次接触Dart时,我正为一个跨平台项目做技术选型。当时团队在Flutter和React Native之间犹豫不决,而Dart作为Flutter的官方语言引起了我的注意。与许多从JavaScript转来的开发者不同,我最初对Dart的印象是"既熟悉又陌生"——它有着类C语言的语法结构,却又在细节处藏着不少精妙设计。
Dart不是那种会在简历上闪闪发光的"明星语言",但当你真正用它构建应用时,会发现它的实用主义设计哲学无处不在。从变量声明方式到异步处理机制,从mixin的应用到isolate的并发模型,每个特性都经过精心打磨。作为一个在2011年由Google推出,2018年随Flutter 1.0正式进入大众视野的语言,Dart用短短几年时间证明了自己在客户端开发领域的独特价值。
在Mac上安装Dart SDK最快捷的方式是通过Homebrew:
bash复制brew tap dart-lang/dart
brew install dart
但实际工作中,我们往往需要管理多个Dart版本。推荐使用dart-versions这个第三方工具,它类似于nvm之于Node.js。安装后可以这样切换版本:
bash复制dart-versions install 3.0.6
dart-versions use 3.0.6
重要提示:Flutter项目对Dart版本有严格要求,务必查看项目根目录下的
pubspec.yaml中标注的SDK约束条件,例如:yaml复制environment: sdk: '>=2.18.0 <3.0.0'
VS Code+Dart插件组合是大多数开发者的选择,但Android Studio/IntelliJ IDEA的Dart插件提供了更完整的工具链支持。我个人的配置方案是:
在VS Code中务必安装以下插件:
创建hello.dart文件:
dart复制void main() {
var greeting = 'Hello, Dart!';
print(greeting);
}
运行方式有多种:
dart run hello.dartdart compile exe hello.dartdart compile aot-snapshot hello.dart性能小贴士:生产环境建议使用AOT编译,启动速度比JIT模式快3-5倍
Dart是强类型语言,但支持类型推断。变量声明有四种方式:
dart复制var a = 'implicit'; // 类型推断
String b = 'explicit'; // 显式类型
dynamic c = 'anything'; // 动态类型
final d = 'immutable'; // 运行时常量
const e = 'compile-constant';// 编译时常量
类型安全是Dart的核心设计原则。在开发模式下,所有类型检查都是严格的;而在生产模式中,编译器会进行优化,但类型安全性依然保持。
Dart函数的几个特点:
dart复制// 常规函数
int add(int a, int b) {
return a + b;
}
// 箭头函数(单行表达式)
int arrowAdd(int a, int b) => a + b;
// 命名参数(用{}包裹)
void namedParams({required String name, int age = 18}) {
print('$name is $age years old');
}
// 可选位置参数(用[]包裹)
void positionalParams(String name, [int? age]) {
print(age != null ? '$name: $age' : name);
}
最佳实践:当参数超过3个时,建议使用命名参数提高可读性
Dart的异步处理基于Future和async/await,比JavaScript的Promise更直观:
dart复制Future<String> fetchUser() async {
await Future.delayed(Duration(seconds: 1)); // 模拟网络请求
return 'User data';
}
void main() async {
print('Fetching...');
final user = await fetchUser();
print(user);
}
对于流式数据处理,可以使用Stream:
dart复制Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
void main() async {
await for (final num in countStream(5)) {
print(num);
}
}
Dart的集合操作非常丰富:
dart复制// List的高级用法
var numbers = [1, 2, 3];
numbers
.where((n) => n > 1)
.map((n) => n * 2)
.forEach(print);
// Set运算
var setA = {1, 2, 3};
var setB = {3, 4, 5};
print(setA.union(setB)); // {1, 2, 3, 4, 5}
print(setA.intersection(setB)); // {3}
// Map转换
var map = {'a': 1, 'b': 2};
map.update('a', (v) => v + 1);
print(map); // {'a': 2, 'b': 2}
Dart的字符串插值和原始字符串:
dart复制var name = 'Dart';
var message = '''
Hello $name!
Version: ${name.length}.0
''';
var rawString = r'Raw \n string'; // 不转义
日期操作示例:
dart复制var now = DateTime.now();
var later = now.add(Duration(hours: 2));
var difference = later.difference(now);
print(difference.inMinutes); // 120
典型的Dart项目结构:
code复制my_app/
├── bin/ // 可执行文件
│ └── main.dart
├── lib/ // 库代码
│ ├── src/ // 实现代码
│ └── my_app.dart // 公开API
├── test/ // 测试代码
├── pubspec.yaml // 项目配置
└── README.md
pubspec.yaml示例:
yaml复制name: my_app
description: A sample Dart application
version: 1.0.0
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
http: ^1.1.0
intl: ^0.18.0
dev_dependencies:
test: ^1.21.0
lints: ^2.0.0
常用命令:
bash复制dart pub get # 安装依赖
dart pub upgrade # 升级依赖
dart pub publish # 发布包
版本控制技巧:
^1.1.0表示允许1.1.0及以上但不包括2.0.0的版本
在VS Code中调试Dart程序:
.vscode/launch.jsonjson复制{
"version": "0.2.0",
"configurations": [
{
"name": "Dart",
"request": "launch",
"type": "dart",
"program": "bin/main.dart"
}
]
}
高级调试功能:
使用Dart DevTools进行性能分析:
bash复制dart devtools
关键指标:
常见错误:
dart复制var list = ['a', 'b', 'c'];
// 错误写法:int length = list[0].length;
// 正确写法:
int length = (list[0] as String).length;
安全转换模式:
dart复制var object = possiblyString();
if (object is String) {
print(object.length);
}
Dart的空安全特性要求显式处理可能为null的值:
dart复制String? nullableString = maybeGetString();
// 错误:print(nullableString.length);
// 正确方式:
print(nullableString?.length ?? 0);
正确处理Future错误:
dart复制Future<void> fetchData() async {
try {
var data = await http.get(url);
} on SocketException catch (e) {
print('Network error: $e');
} on HttpException catch (e) {
print('HTTP error: $e');
} catch (e, stack) {
print('Unexpected error: $e');
print(stack);
}
}
建议深入理解:
必备工具:
练手项目方向: