Dart 语法完全指南:从入门到精通(附详细代码示例)
一、环境配置
Dart环境安装
安装方式:
- 访问 dart.dev 下载SDK
- 使用包管理器:
- Windows:
choco install dart-sdk - macOS:
brew install dart - Linux:
sudo apt-get install dart
- Windows:
验证安装:
dart --version
二、基础语法
2.1 变量与常量
Dart变量声明
// 显式声明类型
String name = 'Dart';
int age = 10;
// 类型推断(使用 var)
var city = 'Beijing'; // 自动推断为 String
var count = 100; // 自动推断为 int
// 延迟初始化
String? email; // 可空类型
late String description; // 延迟初始化
const 常量
- 编译时常量:值在编译期就确定
- 深层不可变:对象及其内容都不可变
const PI = 3.14159;
const List<int> nums = [1, 2, 3]; // 不可修改的列表
// nums.add(4); // 错误!不能修改
final 常量
- 运行时常量:值在运行时确定,但只能赋值一次
- 浅层不可变:引用不可变,但对象内容可能可变
final currentTime = DateTime.now(); // 运行时才知道值
final List<int> numbers = [1, 2, 3];
numbers.add(4); // 可以!列表内容可修改
// numbers = [5, 6]; // 错误!不能重新赋值
dynamic 类型
- 动态类型,可以赋任何值,关闭类型检查
dynamic value = 'Hello';
value = 123; // 可以
value = true; // 可以
print(value.anyMethod()); // 编译通过,但运行时可能报错
空安全机制
// 非空类型(默认)
String name = 'Dart';
// name = null; // 错误!
// 可空类型(使用 ?)
String? nickname;
nickname = null; // 正确
// 空值断言(!)
String? value = 'Hello';
print(value!.length); // 确信不为null时使用
// 空值合并运算符(??)
String? name;
String displayName = name ?? 'Guest'; // name为null时使用'Guest'
// 条件访问(?.)
String? text;
print(text?.length); // text为null时返回null,不报错
2.2 数据类型
String(字符串)
// 单引号或双引号
String str1 = 'Hello';
String str2 = "World";
// 字符串拼接
String fullName = 'John' + ' ' + 'Doe';
String message = 'Hello' ' ' 'World'; // 相邻字符串自动拼接
// 字符串插值
String name = 'Dart';
int version = 3;
print('$name $version'); // Dart 3
print('${name.toUpperCase()}'); // DART
// 多行字符串
String multiLine = '''
这是第一行
这是第二行
这是第三行
''';
// 原始字符串(r前缀)
String path = r'C:\Users\name'; // 不转义反斜杠
数字类型
// int - 整数
int count = 10;
int hex = 0xDEADBEEF;
// double - 浮点数
double price = 19.99;
double exponent = 1.42e5; // 科学计数法
// num - int 和 double 的父类
num value1 = 10;
num value2 = 10.5;
// 常用方法
int a = 5;
double b = 3.14159;
print(a.isEven); // false
print(b.toStringAsFixed(2)); // 3.14
print(int.parse('42')); // 字符串转int
print(double.parse('3.14')); // 字符串转double
布尔类型
bool isActive = true;
bool isCompleted = false;
// 布尔运算
bool result = !isActive; // 取反
bool and = isActive && isCompleted;
bool or = isActive || isCompleted;
列表类型(List)
// 创建列表
List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['apple', 'banana', 'orange'];
// 访问元素
print(numbers[0]); // 1
print(numbers.length); // 5
// 添加元素
numbers.add(6);
numbers.addAll([7, 8, 9]);
// 删除元素
numbers.remove(3); // 删除值为3的元素
numbers.removeAt(0); // 删除索引0的元素
// 常用方法
print(numbers.first); // 第一个元素
print(numbers.last); // 最后一个元素
print(numbers.isEmpty); // 是否为空
numbers.forEach((num) => print(num)); // 遍历
// 不可变列表
const fixedList = [1, 2, 3];
// 扩展运算符
var list1 = [1, 2, 3];
var list2 = [0, ...list1]; // [0, 1, 2, 3]
Map(映射)
// 创建 Map
Map<String, int> ages = {
'Alice': 25,
'Bob': 30,
'Charlie': 35
};
// 访问元素
print(ages['Alice']); // 25
// 添加/修改元素
ages['David'] = 28;
ages['Alice'] = 26;
// 删除元素
ages.remove('Bob');
// 常用方法
print(ages.keys); // 所有键
print(ages.values); // 所有值
print(ages.length); // 元素个数
print(ages.isEmpty); // 是否为空
print(ages.containsKey('Alice')); // 是否包含键
// 遍历
ages.forEach((key, value) {
print('$key: $value');
});
2.3 运算符
算术运算符和赋值运算符
// 算术运算符
int a = 10, b = 3;
print(a + b); // 13 加法
print(a - b); // 7 减法
print(a * b); // 30 乘法
print(a / b); // 3.333... 除法(返回double)
print(a ~/ b); // 3 整除
print(a % b); // 1 取模
// 赋值运算符
int x = 5;
x += 3; // x = x + 3 (8)
x -= 2; // x = x - 2 (6)
x *= 2; // x = x * 2 (12)
x ~/= 3; // x = x ~/ 3 (4)
// 自增自减
int count = 0;
count++; // 后置自增
++count; // 前置自增
count--; // 后置自减
--count; // 前置自减
// 空值赋值(??=)
String? name;
name ??= 'Guest'; // name为null时才赋值
比较运算符和逻辑运算符
// 比较运算符
int a = 5, b = 10;
print(a == b); // false 等于
print(a != b); // true 不等于
print(a > b); // false 大于
print(a < b); // true 小于
print(a >= b); // false 大于等于
print(a <= b); // true 小于等于
// 逻辑运算符
bool x = true, y = false;
print(x && y); // false 逻辑与
print(x || y); // true 逻辑或
print(!x); // false 逻辑非
// 类型判断运算符
var value = 'Hello';
print(value is String); // true
print(value is! int); // true
三、流程控制
3.1 条件语句
if分支和三元运算
// if-else
int score = 85;
if (score >= 90) {
print('优秀');
} else if (score >= 60) {
print('及格');
} else {
print('不及格');
}
// 三元运算符
String result = score >= 60 ? '及格' : '不及格';
// 空值判断简写
String? name;
print(name ?? 'Guest'); // 等同于 name != null ? name : 'Guest'
switch_case
String grade = 'A';
switch (grade) {
case 'A':
print('优秀');
break;
case 'B':
print('良好');
break;
case 'C':
print('及格');
break;
default:
print('不及格');
}
// Dart 3.0+ 支持增强的 switch 表达式
var result = switch (grade) {
'A' => '优秀',
'B' => '良好',
'C' => '及格',
_ => '不及格'
};
3.2 循环语句
while循环
// while 循环
int i = 0;
while (i < 5) {
print(i);
i++;
}
// do-while 循环(至少执行一次)
int j = 0;
do {
print(j);
j++;
} while (j < 5);
for循环
// 基本 for 循环
for (int i = 0; i < 5; i++) {
print(i);
}
// for-in 循环
List<String> fruits = ['apple', 'banana', 'orange'];
for (var fruit in fruits) {
print(fruit);
}
// forEach 方法
fruits.forEach((fruit) {
print(fruit);
});
// break 和 continue
for (int i = 0; i < 10; i++) {
if (i == 3) continue; // 跳过3
if (i == 8) break; // 在8处停止
print(i);
}
四、函数
4.1 函数基础
函数定义
// 基本函数定义
void sayHello() {
print('Hello!');
}
// 有返回值的函数
String greet(String name) {
return 'Hello, $name!';
}
// 简写(箭头函数,适用于单行表达式)
String greet2(String name) => 'Hello, $name!';
// 返回类型可选(不推荐省略)
add(int a, int b) {
return a + b;
}
必传参数和可选位置参数
// 必传参数
int add(int a, int b) {
return a + b;
}
// 可选位置参数(用 [] 包裹,可提供默认值)
String introduce(String name, [int? age, String city = 'Beijing']) {
if (age != null) {
return '$name, $age years old, from $city';
}
return '$name from $city';
}
// 调用示例
print(introduce('Alice')); // Alice from Beijing
print(introduce('Bob', 25)); // Bob, 25 years old, from Beijing
print(introduce('Charlie', 30, 'Shanghai')); // Charlie, 30 years old, from Shanghai
可选命名参数
// 命名参数(用 {} 包裹)
void createUser({
required String name, // required 表示必传
int age = 18, // 有默认值
String? email // 可选,可为null
}) {
print('Name: $name, Age: $age, Email: $email');
}
// 调用时使用参数名
createUser(name: 'Alice');
createUser(name: 'Bob', age: 25, email: 'bob@example.com');
// 命名参数的优点:顺序无关,更清晰
void setStyle({String? color, double? size, bool? bold}) {
// ...
}
setStyle(bold: true, color: 'red'); // 顺序可以任意
匿名函数和箭头函数
// 匿名函数
var list = [1, 2, 3];
list.forEach((item) {
print(item * 2);
});
// 箭头函数(单行表达式)
list.forEach((item) => print(item * 2));
// 将函数赋值给变量
var multiply = (int a, int b) => a * b;
print(multiply(3, 4)); // 12
// 函数作为参数
void executeOperation(int a, int b, Function operation) {
print(operation(a, b));
}
executeOperation(5, 3, (a, b) => a + b); // 8
executeOperation(5, 3, (a, b) => a * b); // 15
// 闭包
Function makeAdder(int addBy) {
return (int i) => i + addBy;
}
var add2 = makeAdder(2);
var add5 = makeAdder(5);
print(add2(3)); // 5
print(add5(3)); // 8
五、面向对象编程
5.1 类的基础
类的定义
class Person {
String name;
int age;
// 方法
void introduce() {
print('I am $name, $age years old.');
}
}
// 使用类
var person = Person();
person.name = 'Alice';
person.age = 25;
person.introduce(); // I am Alice, 25 years old.
类的默认构造函数
class Person {
String name;
int age;
// 默认构造函数
Person(String name, int age) {
this.name = name;
this.age = age;
}
void introduce() {
print('I am $name, $age years old.');
}
}
// 使用
var person = Person('Bob', 30);
person.introduce();
类的命名构造函数
class Person {
String name;
int age;
// 默认构造函数
Person(this.name, this.age);
// 命名构造函数
Person.guest() {
name = 'Guest';
age = 0;
}
Person.fromJson(Map<String, dynamic> json) {
name = json['name'];
age = json['age'];
}
}
// 使用命名构造函数
var guest = Person.guest();
var person = Person.fromJson({'name': 'Charlie', 'age': 28});
类构造函数的语法糖写法
class Person {
String name;
int age;
String? email;
// 语法糖:直接在参数列表中初始化
Person(this.name, this.age, [this.email]);
// 命名参数的语法糖
Person.withEmail({
required this.name,
required this.age,
this.email
});
}
// 使用
var p1 = Person('Alice', 25);
var p2 = Person.withEmail(name: 'Bob', age: 30, email: 'bob@example.com');
类的公有属性和私有属性
class BankAccount {
String accountNumber; // 公有属性
double _balance; // 私有属性(以_开头)
BankAccount(this.accountNumber, this._balance);
// 公有方法
double getBalance() {
return _balance;
}
// 私有方法
void _updateBalance(double amount) {
_balance += amount;
}
void deposit(double amount) {
if (amount > 0) {
_updateBalance(amount);
}
}
// Getter
double get balance => _balance;
// Setter
set balance(double value) {
if (value >= 0) {
_balance = value;
}
}
}
// 使用
var account = BankAccount('123456', 1000);
print(account.balance); // 使用getter:1000
account.deposit(500);
print(account.balance); // 1500
account.balance = 2000; // 使用setter
5.2 类的高级特性
类的继承
// 父类
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
// 子类继承父类
class Dog extends Animal {
String breed;
// 调用父类构造函数
Dog(String name, this.breed) : super(name);
// 重写父类方法
void eat() {
print('$name the dog is eating dog food');
}
// 子类特有方法
void bark() {
print('$name is barking: Woof!');
}
}
// 使用
var dog = Dog('Buddy', 'Golden Retriever');
dog.eat(); // Buddy the dog is eating dog food
dog.bark(); // Buddy is barking: Woof!
类的多态
class Animal {
void makeSound() {
print('Some sound');
}
}
class Dog extends Animal {
void makeSound() {
print('Woof!');
}
}
class Cat extends Animal {
void makeSound() {
print('Meow!');
}
}
// 多态:父类引用指向子类对象
void animalSound(Animal animal) {
animal.makeSound();
}
// 使用
animalSound(Dog()); // Woof!
animalSound(Cat()); // Meow!
抽象类和接口实现
// 抽象类(不能实例化)
abstract class Shape {
// 抽象方法(没有方法体)
double calculateArea();
// 普通方法
void display() {
print('Area: ${calculateArea()}');
}
}
class Circle extends Shape {
double radius;
Circle(this.radius);
double calculateArea() {
return 3.14 * radius * radius;
}
}
// 接口实现(使用 implements)
class Rectangle implements Shape {
double width;
double height;
Rectangle(this.width, this.height);
double calculateArea() {
return width * height;
}
void display() {
print('Rectangle area: ${calculateArea()}');
}
}
// 使用
Shape circle = Circle(5);
circle.display(); // Area: 78.5
Shape rect = Rectangle(4, 6);
rect.display(); // Rectangle area: 24.0
类的混入(Mixin)
// Mixin 定义
mixin Flyable {
void fly() {
print('Flying in the sky');
}
}
mixin Swimmable {
void swim() {
print('Swimming in water');
}
}
// 使用 with 关键字混入
class Duck extends Animal with Flyable, Swimmable {
Duck(String name) : super(name);
void eat() {
print('$name is eating');
}
}
// 使用
var duck = Duck('Donald');
duck.eat(); // Donald is eating
duck.fly(); // Flying in the sky
duck.swim(); // Swimming in water
5.3 泛型
泛型的使用
// 泛型类
class Box<T> {
T value;
Box(this.value);
T getValue() {
return value;
}
}
// 使用泛型
var intBox = Box<int>(123);
var stringBox = Box<String>('Hello');
print(intBox.getValue()); // 123
print(stringBox.getValue()); // Hello
// 泛型函数
T getFirst<T>(List<T> list) {
return list[0];
}
print(getFirst<int>([1, 2, 3])); // 1
print(getFirst<String>(['a', 'b', 'c'])); // a
// 泛型约束
class NumberBox<T extends num> {
T value;
NumberBox(this.value);
T add(T other) {
return (value + other) as T;
}
}
var numBox = NumberBox<int>(10);
print(numBox.add(5)); // 15
六、异步编程
6.1 Future
异步编程-事件循环
Dart 是单线程语言,使用事件循环(Event Loop)处理异步操作。
事件循环机制:
- 主线程(Microtask Queue):优先级最高
- 事件队列(Event Queue):处理 I/O、定时器等异步事件
void main() {
print('1');
// Future(Event Queue)
Future(() => print('2'));
// Microtask(优先级更高)
scheduleMicrotask(() => print('3'));
print('4');
}
// 输出顺序:1 4 3 2
Future的基本使用
Future 表示一个异步操作的最终完成(或失败)及其结果值。
// 创建 Future
Future<String> fetchData() {
return Future.delayed(
Duration(seconds: 2),
() => 'Data loaded'
);
}
// 使用 then 处理结果
void main() {
print('Start');
fetchData().then((data) {
print(data); // 2秒后输出:Data loaded
});
print('End'); // 立即输出
}
// 输出:Start End Data loaded
// 处理错误
Future<int> riskyOperation() {
return Future.delayed(
Duration(seconds: 1),
() => throw Exception('Something went wrong!')
);
}
riskyOperation()
.then((value) => print('Success: $value'))
.catchError((error) => print('Error: $error'))
.whenComplete(() => print('Operation complete'));
Future的链式调用
Future<String> login(String username) {
return Future.delayed(
Duration(seconds: 1),
() => 'Token_$username'
);
}
Future<String> fetchUserInfo(String token) {
return Future.delayed(
Duration(seconds: 1),
() => 'User info for $token'
);
}
Future<List<String>> fetchPosts(String userInfo) {
return Future.delayed(
Duration(seconds: 1),
() => ['Post 1', 'Post 2', 'Post 3']
);
}
// 链式调用
void main() {
login('alice')
.then((token) {
print('Logged in: $token');
return fetchUserInfo(token);
})
.then((userInfo) {
print('User info: $userInfo');
return fetchPosts(userInfo);
})
.then((posts) {
print('Posts: $posts');
})
.catchError((error) {
print('Error: $error');
});
}
Future的async和await
async/await 使异步代码看起来像同步代码,更易读易维护。
// 使用 async/await 改写上面的例子
Future<void> getUserData() async {
try {
print('Start loading...');
// await 等待 Future 完成
String token = await login('alice');
print('Logged in: $token');
String userInfo = await fetchUserInfo(token);
print('User info: $userInfo');
List<String> posts = await fetchPosts(userInfo);
print('Posts: $posts');
print('All done!');
} catch (error) {
print('Error: $error');
}
}
void main() {
getUserData();
}
// 多个异步操作并行执行
Future<void> loadMultipleData() async {
// 并行执行多个异步操作
var results = await Future.wait([
fetchData1(),
fetchData2(),
fetchData3()
]);
print('All data loaded: $results');
}
// async 函数必须返回 Future
Future<int> calculate() async {
await Future.delayed(Duration(seconds: 1));
return 42;
}
// 使用 async*
Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i; // 生成值
}
}
// 使用 Stream
void main() async {
await for (var value in countStream(5)) {
print(value); // 每秒输出一个数字:1, 2, 3, 4, 5
}
}
Dart语法全面解析与实践
2093

被折叠的 条评论
为什么被折叠?



