第2章:Dart 语言基础
一、变量与类型
Dart 是强类型语言,但也支持类型推断。
// 显式声明类型
int age = 18;
String name = "Eric";
// 类型推断
var score = 95.5; // 推断为 double
final city = "Beijing"; // 只能赋值一次
const PI = 3.14; // 编译时常量
🔹 区别说明:
var:编译期推断类型,但可以重新赋值。final:只能赋值一次,运行时常量。const:编译时常量,性能更优。
二、函数的定义与使用
// 普通函数
int add(int a, int b) {
return a + b;
}
// 简写函数
int multiply(int a, int b) => a * b;
// 可选参数
String greet(String name, [String suffix = '']) {
return "Hello, $name$suffix";
}
// 命名参数
String introduce({required String name, int age = 18}) {
return "Name: $name, Age: $age";
}
三、类与对象
class Person {
String name;
int age;
// 构造函数
Person(this.name, this.age);
// 命名构造函数
Person.named({required this.name, required this.age});
void sayHello() {
print("Hi, I'm $name.");
}
}
// 使用
void main() {
var p = Person("Eric", 25);
p.sayHello();
}
四、集合(List / Set / Map)
List<String> fruits = ['Apple', 'Banana'];
Set<int> nums = {1, 2, 3};
Map<String, int> scores = {'Math': 95, 'English': 88};
// 常见操作
fruits.add("Orange");
nums.contains(2); // true
scores['Math'] = 100; // 修改值
集合的展开与条件成员
var list1 = [1, 2];
var list2 = [0, ...list1]; // [0, 1, 2]
var list3 = [if (true) 100]; // 条件插入
五、控制流语句
if (score > 90) {
print("Excellent");
} else {
print("Keep trying");
}
for (var i = 0; i < 3; i++) {
print(i);
}
while (true) {
break;
}
六、泛型
List<int> numbers = <int>[1, 2, 3];
Map<String, double> prices = {'apple': 3.5};
// 自定义泛型类
class Box<T> {
T value;
Box(this.value);
}
七、异步编程:Future & async/await
Dart 的异步使用 Future 表示一个“未来的值”。
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return 'Data Loaded';
}
void main() async {
print("Loading...");
String result = await fetchData();
print(result); // Data Loaded
}
异步函数需用 async 修饰,等待异步结果使用 await。
八、常见问题解析
❓ async/await 执行顺序问题
Future<void> test() async {
print("1");
await Future.delayed(Duration(seconds: 1));
print("2");
print("3");
}
void main() {
test();
print("4");
}
输出顺序为:
1
4
2
3
✅ 原因解析:await 会暂停当前函数的执行,先执行主线程后续代码。
❓ Dart 的 null 安全机制
Dart 支持 null 安全,默认变量不能为 null,除非你显式指定:
String name = 'Eric'; // 不能为空
String? nickname = null; // 可以为空
访问可空变量时需小心:
print(nickname?.length); // null 安全调用
print(nickname!.length); // 强制非空(慎用)
函数参数中也要标明是否可以为 null:
void sayHello(String? name) {
print("Hello, ${name ?? 'Guest'}");
}