1. 为什么选择Dart语言
作为一名从Java和JavaScript转型过来的开发者,我最初接触Dart时也带着疑问:为什么Google要创造这门新语言?经过两年多的实际项目使用,我发现Dart在客户端开发领域确实有其独特优势。
Dart最显著的特点是它同时支持JIT(Just-In-Time)和AOT(Ahead-Of-Time)编译模式。在开发阶段使用JIT可以实现热重载(Hot Reload),这是Flutter开发中令人惊艳的功能——保存代码后界面几乎实时更新。而在发布时使用AOT编译,又能获得接近原生性能的执行效率。这种双模式设计解决了开发效率和运行效率难以兼得的问题。
另一个重要特性是Dart的强类型系统。虽然它也支持动态类型(通过dynamic关键字),但默认情况下是静态类型检查。这比JavaScript更有利于构建大型应用,可以在编译期捕获类型错误。同时,它的类型系统又不像Java那样严格,通过类型推断(var/final)让代码保持简洁。
dart复制// 类型推断示例
var name = 'Dart'; // 推断为String类型
final version = 2.19; // 推断为double类型
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Dart基础语法结构
2.1 变量与常量声明
Dart提供了多种变量声明方式,每种都有其适用场景:
-
var:最常用的声明方式,类型由编译器推断
dart复制var message = 'Hello Dart'; // 推断为String -
明确类型声明:提高代码可读性
dart复制String greeting = 'Hello'; int counter = 0; -
final:运行时常量(赋值后不可修改)
dart复制final city = 'Beijing'; // city = 'Shanghai'; // 错误:final变量不能重新赋值 -
const:编译时常量(值在编译时确定)
dart复制const pi = 3.14159; const List<int> nums = [1, 2, 3];
实际经验:在Flutter widget构建中,应优先使用final和const,这有助于Flutter优化重建过程。
2.2 基本数据类型
Dart的所有类型都是对象(没有Java那样的原始类型),常见类型包括:
-
数字类型:
dart复制int age = 30; // 整数 double price = 9.99; // 浮点数 num flexible = 10; // int和double的父类 flexible = 10.5; // 合法 -
字符串:
Dart字符串支持多行和模板语法:dart复制String multiLine = ''' 这是 多行 字符串 '''; String name = 'Alice'; String greeting = 'Hello, $name!'; // 模板字符串 -
布尔类型:
Dart的bool类型只有true和false两个值,与JavaScript不同,其他值不会自动转换为bool:dart复制bool isActive = true; // if (1) {} // 错误:非bool条件 -
列表(List):
Dart的列表类似于其他语言的数组:dart复制List<String> fruits = ['apple', 'banana']; fruits.add('orange'); // 添加元素 -
映射(Map):
键值对集合:dart复制Map<String, int> scores = { 'Alice': 100, 'Bob': 90, }; print(scores['Alice']); // 100
3. 控制流程与函数
3.1 流程控制语句
Dart的控制语句与大多数C风格语言类似,但有一些细节差异:
-
if-else:
dart复制if (year >= 2023) { print('Future'); } else if (year > 2000) { print('21st century'); } else { print('Past'); } -
for循环:
Dart支持标准for循环和for-in迭代:dart复制// 传统for循环 for (var i = 0; i < 5; i++) { print(i); } // for-in循环 var numbers = [1, 2, 3]; for (var n in numbers) { print(n); } -
while和do-while:
dart复制while (!isDone) { doSomething(); } do { print('至少执行一次'); } while (false); -
switch-case:
Dart的switch支持字符串和编译时常量:dart复制var command = 'OPEN'; switch (command) { case 'OPEN': executeOpen(); break; // 必须显式break case 'CLOSE': executeClose(); break; default: executeUnknown(); }
3.2 函数定义与使用
Dart的函数是一等公民,可以作为参数传递和变量赋值:
-
基本函数:
dart复制int add(int a, int b) { return a + b; } -
箭头函数(单行函数简写):
dart复制int multiply(int a, int b) => a * b; -
可选参数:
Dart支持命名可选参数和位置可选参数:dart复制// 命名可选参数 void enableFlags({bool bold, bool hidden}) {...} enableFlags(bold: true); // 位置可选参数 String say(String from, [String to, String message]) {...} say('Alice', 'Bob'); -
默认参数值:
dart复制void greet({String name = 'Guest'}) { print('Hello, $name!'); }
实战技巧:在Flutter中,命名参数被广泛使用,因为它使widget的构造函数调用更清晰可读。
4. 面向对象编程
4.1 类与对象
Dart是纯面向对象语言,所有类型都继承自Object:
dart复制class Person {
// 实例变量
String name;
int age;
// 构造函数
Person(this.name, this.age);
// 命名构造函数
Person.guest() {
name = 'Guest';
age = 18;
}
// 方法
void introduce() {
print('I am $name, $age years old.');
}
}
// 使用
var p = Person('Alice', 25);
p.introduce();
4.2 继承与接口
Dart使用单继承+多接口混合的方式:
dart复制// 基类
class Animal {
void eat() => print('Eating...');
}
// 接口(隐含的)
abstract class Flyable {
void fly();
}
// 继承+实现
class Bird extends Animal implements Flyable {
@override
void fly() => print('Flying...');
}
4.3 混入(Mixins)
Dart通过mixins实现代码复用:
dart复制mixin Musical {
void playMusic() => print('Playing music...');
}
class Performer with Musical {
// 现在有playMusic方法
}
var p = Performer();
p.playMusic();
5. 异步编程模型
5.1 Future与async/await
Dart使用Future处理异步操作:
dart复制Future<String> fetchUserData() async {
// 模拟网络请求
await Future.delayed(Duration(seconds: 2));
return 'User Data';
}
void main() async {
print('Fetching data...');
final data = await fetchUserData();
print('Received: $data');
}
5.2 Stream处理数据流
对于连续的数据流,Dart提供了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); // 每秒输出一个数字
}
}
6. 空安全与高级特性
6.1 空安全(Null Safety)
Dart的空安全特性要求显式声明可为null的变量:
dart复制String? nullableString = null; // 可能为null
String nonNullableString = 'hello'; // 不能为null
// 安全调用
print(nullableString?.length); // null安全操作符
// 非空断言
print(nullableString!.length); // 开发者确保不为null
6.2 扩展方法
可以为现有类添加新方法:
dart复制extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
}
'42'.parseInt(); // 42
6.3 泛型
Dart支持类型安全的泛型:
dart复制class Box<T> {
final T content;
Box(this.content);
}
var stringBox = Box<String>('secret');
var intBox = Box<int>(42);
7. 实际项目中的Dart使用技巧
经过多个Flutter项目实践,我总结出以下Dart使用经验:
-
代码组织:
- 合理使用part和library组织大型项目
- 遵循Dart官方风格指南(dart format工具)
-
性能优化:
- 在列表操作中使用.whereType()进行安全类型过滤
dart复制var objects = [1, 'two', 3, 'four']; var ints = objects.whereType<int>(); // [1, 3] -
错误处理:
- 优先使用try-catch处理可能失败的异步操作
dart复制try { var data = await fetchData(); } catch (e) { print('Error: $e'); } -
集合操作:
- 充分利用Dart强大的集合操作符
dart复制var numbers = [1, 2, 3]; var squared = numbers.map((n) => n * n).toList(); // [1, 4, 9] -
文档注释:
- 使用///文档注释支持dartdoc生成文档
dart复制/// 计算两个数的和 /// /// [a] 第一个加数 /// [b] 第二个加数 /// 返回两个数的和 int add(int a, int b) => a + b;
Dart作为一门现代语言,其语法设计既考虑了开发效率,又保证了运行性能。特别是在Flutter生态中,掌握Dart的核心语法特性,能够帮助开发者构建更健壮、高效的应用程序。从基础语法到高级特性,Dart提供了一套完整的工具集,适应从简单脚本到复杂应用的各种开发场景。
