【Harmonyos】Flutter开源鸿蒙跨平台训练营 Day 5
Dart核心语法精要(2026版) 本文系统讲解Dart编程语言的四大核心模块:变量、函数、异步编程和类。内容涵盖变量声明(var/final/const)、类型系统与空安全、常用数据类型、函数定义与参数类型、Future异步处理以及async/await语法糖。通过大量可运行代码示例,展示Dart强类型特性、灵活的参数设计和高性能异步模型。特别针对Flutter开发必备的Dart知识进行重点讲解
🚀 Dart基础从入门到精通:变量、函数、异步、类全解析(2026最新版)
🔥 保姆级教学:通过可运行代码+通俗解释,帮你彻底掌握Dart核心语法,零基础也能轻松入门!
引言:为什么要学Dart?
Dart是Google推出的现代化编程语言,不仅是Flutter跨平台开发的官方语言,还可用于后端开发、CLI工具编写等场景。它兼具静态类型安全和动态语言的灵活性,语法简洁易上手,是2026年开发者必备技能之一。
本文将从变量、函数、异步、类四大核心模块入手,结合大量可直接运行的代码实例,帮你快速构建Dart知识体系。每个知识点都配有运行结果和实战建议,确保你能边学边练,真正做到“从理论到实战”的无缝衔接。

一、变量:程序的“数据容器”
变量是存储数据的基本单元,Dart的变量系统兼具强类型特性和灵活的类型推断能力,新手需重点理解以下核心概念:
1. 变量声明:var、final、const的区别
Dart支持类型自动推断,也可显式指定变量类型。核心关键字的区别如下:
| 关键字 | 特点 | 适用场景 |
|---|---|---|
| var | 可重新赋值,类型自动推断 | 临时变量、类型明确的业务场景 |
| final | 不可重新赋值,运行时确定值 | 初始化后无需修改的变量(如用户ID、设备编号) |
| const | 编译时常量,不可变且值需为字面量 | 固定常量(如数学常量、配置参数) |
代码实例:
void main() {
// 1. var:类型推断为String,支持重新赋值
var name = "小明";
name = "小红"; // ✅ 合法:var变量可重新赋值
print(name); // 输出:小红
// 2. final:运行时确定值,不可重新赋值
final age = 18;
// age = 20; ❌ 编译错误:final变量赋值后不可修改
// 3. const:编译时常量,值必须是字面量或常量表达式
const pi = 3.14159;
const circleArea = pi * 5 * 5; // 编译时直接计算结果
print(circleArea); // 输出:78.53975
}
2. 类型系统:强类型与空安全
Dart 2.12+ 引入空安全(Null Safety) 特性,默认禁止变量赋值为null,需显式声明可空类型:
void main() {
// 非空类型(默认):禁止赋值为null
String name = "张三";
// name = null; ❌ 编译错误:非空类型不能赋值为null
// 可空类型(变量类型后加?):允许赋值为null
String? nullableName = null;
nullableName = "李四"; // ✅ 合法:可空类型支持null赋值
// late关键字:延迟初始化(非空类型但暂时不赋值)
late String delayedName;
delayedName = "王五"; // ✅ 后续赋值合法
}
3. 常用数据类型
Dart基础数据类型与主流语言类似,但有细节需注意:
void main() {
// 数值类型:int(整数)、double(浮点数),支持自动类型提升
int a = 10;
double b = 3.14;
print(a + b); // 输出:13.14(int自动转为double)
// 布尔类型:仅true/false,无“非0即真”规则
bool isTrue = true;
if (isTrue) print("条件成立"); // 输出:条件成立
// 字符串:单引号、双引号、多行字符串
String str1 = '单引号';
String str2 = "双引号";
String str3 = '''多行
字符串''';
print(str1 + str2); // 输出:单引号双引号
print("a的值是${a}"); // 插值表达式:输出a的值是10
// 列表(数组):泛型指定元素类型,支持动态增删
List<int> numbers = [1, 2, 3];
numbers.add(4);
print(numbers); // 输出:[1, 2, 3, 4]
// 映射(字典):键值对结构,泛型指定键值类型
Map<String, dynamic> person = {
"name": "小明",
"age": 18
};
print(person["name"]); // 输出:小明
}
二、函数:程序的“功能模块”
函数是实现特定功能的代码块,Dart的函数支持多种参数形式和高阶函数,灵活性极强。
1. 函数定义与调用
基础语法:返回类型 函数名(参数列表) { 函数体 }(无返回值时void可省略)
// 无返回值函数(void可省略)
void printHello() {
print("Hello Dart!");
}
// 有返回值函数:显式指定返回类型为int
int add(int a, int b) {
return a + b;
}
void main() {
printHello(); // 调用无返回值函数:输出Hello Dart!
int result = add(2, 3);
print(result); // 输出:5
}
2. 参数类型:位置参数、命名参数、可选参数
Dart的参数设计灵活,可满足不同业务场景的参数传递需求:
// 1. 位置参数(必传):按顺序传递,缺一不可
void sayHi(String name, int age) {
print("Hi $name, you are $age years old.");
}
// 2. 命名参数(用{}包裹,可选):传参时指定参数名,可设置默认值
void sayHello({String? name, int age = 18}) {
print("Hello ${name ?? 'Guest'}, age $age");
}
// 3. 可选位置参数(用[]包裹):按位置可选传递
void sayGreeting(String message, [String? name]) {
print("$message ${name ?? 'everyone'}");
}
void main() {
sayHi("小明", 18); // 输出:Hi 小明, you are 18 years old.
sayHello(name: "小红"); // 输出:Hello 小红, age 18(age使用默认值)
sayHello(age: 20); // 输出:Hello Guest, age 20(name为null)
sayGreeting("Hi"); // 输出:Hi everyone
sayGreeting("Hi", "小张"); // 输出:Hi 小张
}
3. 箭头函数与匿名函数
简化代码的利器,适合简短逻辑或回调场景:
void main() {
// 箭头函数(单行逻辑):简化函数体,自动返回表达式结果
int multiply(int a, int b) => a * b;
print(multiply(3, 4)); // 输出:12
// 匿名函数(无函数名):常用于集合遍历、回调函数
List<int> numbers = [1, 2, 3];
numbers.forEach((num) => print(num * 2)); // 输出:2、4、6
// 闭包:函数捕获外部变量,即使外部作用域销毁仍可访问
Function makeAdder(int addBy) {
return (int i) => i + addBy;
}
var add5 = makeAdder(5);
print(add5(3)); // 输出:8(捕获了外部变量addBy=5)
}
三、异步编程:Future与async/await
Dart的异步模型基于单线程事件循环,通过Future和async/await处理异步操作(如网络请求、文件读写),避免阻塞主线程。
1. Future:异步操作的“承诺”
Future代表一个“未来可能完成的操作”,类比“快递包裹”——下单后无需等待,包裹送达后再处理:
void main() {
// 模拟网络请求(返回Future<String>)
Future<String> fetchData() {
return Future.delayed(Duration(seconds: 2), () {
return "网络请求结果"; // 2秒后返回数据
});
}
// 处理Future的方式1:then/catchError 链式调用
fetchData().then((data) {
print("成功:$data"); // 异步操作成功时执行
}).catchError((error) {
print("失败:$error"); // 异步操作失败时执行
}).whenComplete(() {
print("操作完成"); // 无论成功/失败都会执行
});
print("主线程继续执行"); // 先输出这句话,异步操作不阻塞主线程
}
运行结果:
主线程继续执行
(等待2秒后)
成功:网络请求结果
操作完成
2. async/await:异步代码同步化
async/await是Future的语法糖,让异步代码看起来像同步代码,可读性更高:
void main() async { // 主函数标记为async(Dart 2.14+支持main函数async)
print("开始请求");
try {
String data = await fetchData(); // 等待Future完成,获取结果
print("成功:$data");
} catch (error) {
print("失败:$error"); // 捕获异步操作异常
} finally {
print("操作完成"); // 无论成功/失败都会执行
}
print("请求结束");
}
// 复用上面的fetchData函数
Future<String> fetchData() {
return Future.delayed(Duration(seconds: 2), () => "网络请求结果");
}
运行结果:
开始请求
(等待2秒后)
成功:网络请求结果
操作完成
请求结束
3. 并发执行:Future.wait
同时执行多个异步操作,等待所有操作完成后统一处理结果(总耗时为最长的异步操作耗时):
void main() async {
// 模拟两个异步请求
Future<String> fetchUser() => Future.delayed(Duration(seconds: 1), () => "用户信息");
Future<String> fetchOrders() => Future.delayed(Duration(seconds: 2), () => "订单信息");
// 并发执行,总耗时2秒(而非1+2=3秒)
List<String> results = await Future.wait([fetchUser(), fetchOrders()]);
print(results); // 输出:[用户信息, 订单信息]
}
四、类:面向对象的核心
Dart是纯面向对象语言(一切皆对象),类是组织代码的基本单元,支持封装、继承、多态等核心特性。
1. 类的定义与构造函数
// 定义Person类:封装姓名、年龄属性和打招呼方法
class Person {
String name;
int age;
// 1. 默认构造函数(语法糖):直接初始化成员变量
Person(this.name, this.age);
// 2. 命名构造函数:支持多个构造函数,满足不同初始化场景
Person.fromBirthYear(String name, int birthYear) {
this.name = name;
this.age = DateTime.now().year - birthYear;
}
// 3. 工厂构造函数:返回实例,常用于单例模式
static final Person _instance = Person("单例", 0);
factory Person.singleton() => _instance;
// 类方法:封装行为
void sayHello() {
print("Hello, I'm $name, $age years old.");
}
}
void main() {
// 使用默认构造函数
Person p1 = Person("小明", 18);
p1.sayHello(); // 输出:Hello, I'm 小明, 18 years old.
// 使用命名构造函数(按出生年份计算年龄)
Person p2 = Person.fromBirthYear("小红", 2000);
p2.sayHello(); // 输出:Hello, I'm 小红, 26 years old.(2026-2000)
// 使用工厂构造函数(单例:多次调用返回同一个实例)
Person p3 = Person.singleton();
Person p4 = Person.singleton();
print(p3 == p4); // 输出:true
}
2. 继承与多态
Dart支持单继承,子类通过extends关键字继承父类,可重写父类方法实现多态:
// 子类Student继承父类Person
class Student extends Person {
String school; // 子类新增属性
// 子类构造函数:必须通过super调用父类构造函数
Student(String name, int age, this.school) : super(name, age);
// 重写父类方法:@override注解标识
void sayHello() {
super.sayHello(); // 调用父类原方法
print("I study at $school."); // 子类扩展逻辑
}
}
void main() {
Student s = Student("小李", 20, "清华大学");
s.sayHello();
}
运行结果:
Hello, I'm 小李, 20 years old.
I study at 清华大学.
3. 混入(Mixin):代码复用的黑科技
Mixin是Dart特有的代码复用方式,允许一个类“混入”多个类的方法(无需继承),解决单继承的局限性:
// 定义Mixin(用mixin关键字,不能实例化)
mixin Runnable {
void run() {
print("正在跑步");
}
}
mixin Swimmable {
void swim() {
print("正在游泳");
}
}
// 类混入多个Mixin:with关键字
class Athlete extends Person with Runnable, Swimmable {
Athlete(String name, int age) : super(name, age);
}
void main() {
Athlete a = Athlete("运动员", 25);
a.run(); // 输出:正在跑步(来自Runnable)
a.swim(); // 输出:正在游泳(来自Swimmable)
a.sayHello(); // 输出:Hello, I'm 运动员, 25 years old.(来自Person)
}
4. 接口与抽象类
- 抽象类:用
abstract修饰,不能实例化,用于定义规范(可包含抽象方法和具体方法)。 - 接口:Dart中每个类都可作为接口,用
implements实现(需重写所有属性和方法)。
// 抽象类:定义动物的通用规范
abstract class Animal {
void eat(); // 抽象方法(无实现,子类必须重写)
void sleep() { // 具体方法(有实现,子类可复用)
print("睡觉");
}
}
// 继承抽象类:重写抽象方法
class Dog extends Animal {
void eat() {
print("狗吃骨头");
}
}
// 实现接口(多个接口):需重写所有方法和属性
class Bird implements Animal, Runnable {
void eat() {
print("鸟吃虫子");
}
void sleep() {
print("鸟站在树枝上睡觉");
}
void run() {
print("鸟快速跑");
}
}
void main() {
Dog dog = Dog();
dog.eat(); // 输出:狗吃骨头
dog.sleep(); // 输出:睡觉
Bird bird = Bird();
bird.eat(); // 输出:鸟吃虫子
bird.run(); // 输出:鸟快速跑
}
五、实战:Dart基础综合案例
通过学生管理系统综合运用以上知识点,实现“加载学生数据→添加学生→展示学生信息”的完整流程:
// 1. 定义顶层Person类
class Person {
String name;
int age;
Person(this.name, this.age);
void sayHello() => print("我是$name,今年$age岁");
}
void main() async {
// 2. 定义学生列表(泛型约束为Student)
List<Student> students = [];
// 3. 函数:添加学生到列表
void addStudent(Student student) {
students.add(student);
print("添加学生:${student.name}");
}
// 4. 异步函数:模拟从服务器加载学生数据
Future<List<Student>> fetchStudents() async {
await Future.delayed(Duration(seconds: 1)); // 模拟网络延迟
return [
Student("小明", 18, "高一(1)班"),
Student("小红", 17, "高一(2)班")
];
}
// 5. 定义Student子类(继承Person)
class Student extends Person {
String className;
Student(String name, int age, this.className) : super(name, age);
void sayHello() {
print("我是$className的$name,今年$age岁");
}
}
// 执行流程
print("开始加载学生数据...");
List<Student> fetchedStudents = await fetchStudents();
fetchedStudents.forEach(addStudent);
print("\n学生列表:");
students.forEach((s) => s.sayHello());
}
运行结果:
开始加载学生数据...
(等待1秒后)
添加学生:小明
添加学生:小红
学生列表:
我是高一(1)班的小明,今年18岁
我是高一(2)班的小红,今年17岁
六、总结与学习建议
核心要点回顾
- 变量:掌握
var/final/const的区别,理解空安全的核心逻辑; - 函数:灵活运用位置参数、命名参数,熟悉箭头函数和闭包;
- 异步:用
Future处理异步操作,async/await简化异步代码; - 类:掌握构造函数、继承、Mixin、抽象类/接口的使用场景。
学习建议
- 多写代码:每个知识点至少写3个不同的例子,加深理解;
- 调试代码:用
print或IDE调试工具查看变量变化,理解执行流程; - 官方文档:优先阅读Dart官网(dart.dev),获取最新语法和最佳实践;
- 项目实践:用Dart写小项目(如TodoList、计算器),将知识点落地。
常见误区
- 混淆
final和const:const是编译时常量,final是运行时常量; - 忘记
async修饰函数:使用await的函数必须标记为async; - 继承与接口混淆:
extends是继承(复用代码),implements是实现接口(遵守规范); - 空安全使用不当:非空类型直接赋值
null,或可空类型未做判空处理。
更多推荐



所有评论(0)