Dart 语言基础
Dart 是 Flutter 的核心语言,本章将介绍 Dart 语言的基础语法和核心概念。
变量和数据类型
变量声明
Dart 提供了多种变量声明方式:
// 使用 var 自动推断类型
var name = '张三';
var age = 25;
// 显式声明类型
String city = '北京';
int score = 95;
// 使用 final 声明不可变变量(运行时确定值)
final currentTime = DateTime.now();
// 使用 const 声明编译时常量
const pi = 3.14159;
const maxRetry = 3;
final 和 const 的区别:
final:变量只能被赋值一次,值在运行时确定const:编译时常量,值在编译时就必须确定
final name = '张三'; // 正确
// name = '李四'; // 错误!final 变量不能重新赋值
const pi = 3.14; // 正确
// const now = DateTime.now(); // 错误!const 必须是编译时常量
内置数据类型
数值类型
// 整数
int age = 25;
int hexValue = 0xFF; // 十六进制
int bigNumber = 1000000000000000000;
// 浮点数
double price = 19.99;
double scientific = 2.5e5; // 250000.0
// num 可以存储整数或浮点数
num value = 10;
value = 10.5; // 可以赋值为浮点数
字符串
// 单引号和双引号
String name1 = '张三';
String name2 = "李四";
// 多行字符串
String poem = '''
静夜思
床前明月光,
疑是地上霜。
''';
// 字符串插值
String greeting = '你好,$name1!';
String calculation = '2 + 3 = ${2 + 3}';
// 原始字符串(不处理转义字符)
String path = r'C:\Users\Admin\Documents';
// 常用字符串方法
String text = 'Hello, Dart!';
print(text.length); // 12
print(text.toUpperCase()); // HELLO, DART!
print(text.toLowerCase()); // hello, dart!
print(text.contains('Dart')); // true
print(text.substring(0, 5)); // Hello
print(text.split(',')); // [Hello, Dart!]
布尔类型
bool isActive = true;
bool isDeleted = false;
// 布尔运算
bool result = (5 > 3) && (10 < 20); // true
列表(List)
// 创建列表
List<int> numbers = [1, 2, 3, 4, 5];
var names = ['张三', '李四', '王五'];
// 不可变列表
const colors = ['red', 'green', 'blue'];
// 访问元素
print(numbers[0]); // 1
// 添加元素
numbers.add(6);
numbers.addAll([7, 8]);
// 插入元素
numbers.insert(0, 0);
// 删除元素
numbers.remove(3);
numbers.removeAt(0);
// 其他常用方法
print(numbers.length); // 长度
print(numbers.contains(5)); // 是否包含
print(numbers.indexOf(3)); // 查找索引
print(numbers.sublist(0, 3)); // 子列表
// 遍历列表
for (var num in numbers) {
print(num);
}
numbers.forEach((num) => print(num));
// 映射和过滤
var squared = numbers.map((n) => n * n).toList();
var evens = numbers.where((n) => n % 2 == 0).toList();
集合(Set)
// 创建集合(不包含重复元素)
Set<String> fruits = {'苹果', '香蕉', '橙子'};
// 添加元素
fruits.add('葡萄');
fruits.addAll(['苹果', '西瓜']); // '苹果'不会重复添加
// 删除元素
fruits.remove('香蕉');
// 集合运算
Set<int> set1 = {1, 2, 3, 4};
Set<int> set2 = {3, 4, 5, 6};
print(set1.union(set2)); // {1, 2, 3, 4, 5, 6} 并集
print(set1.intersection(set2)); // {3, 4} 交集
print(set1.difference(set2)); // {1, 2} 差集
映射(Map)
// 创建映射
Map<String, int> scores = {
'张三': 90,
'李四': 85,
'王五': 95,
};
// 访问元素
print(scores['张三']); // 90
// 添加或修改元素
scores['赵六'] = 88;
scores['张三'] = 92; // 修改已存在的键
// 删除元素
scores.remove('李四');
// 检查键和值
print(scores.containsKey('张三')); // true
print(scores.containsValue(95)); // true
// 获取所有键和值
print(scores.keys); // (张三, 王五, 赵六)
print(scores.values); // (92, 95, 88)
// 遍历 Map
scores.forEach((name, score) {
print('$name: $score');
});
运算符
算术运算符
int a = 10, b = 3;
print(a + b); // 13 加法
print(a - b); // 7 减法
print(a * b); // 30 乘法
print(a / b); // 3.333... 除法
print(a ~/ b); // 3 整除
print(a % b); // 1 取余
比较运算符
print(5 == 5); // true 等于
print(5 != 3); // true 不等于
print(5 > 3); // true 大于
print(5 < 3); // false 小于
print(5 >= 5); // true 大于等于
print(5 <= 3); // false 小于等于
逻辑运算符
bool a = true, b = false;
print(a && b); // false 逻辑与
print(a || b); // true 逻辑或
print(!a); // false 逻辑非
条件运算符
// 三元运算符
String result = (5 > 3) ? '正确' : '错误';
// 空值合并运算符
String name = null;
String displayName = name ?? '匿名用户'; // 如果 name 为 null,使用默认值
// 空值感知运算符
String? nullableName;
print(nullableName?.length); // 如果为 null,返回 null 而不是报错
控制流
条件语句
// if-else
int score = 85;
if (score >= 90) {
print('优秀');
} else if (score >= 80) {
print('良好');
} else if (score >= 60) {
print('及格');
} else {
print('不及格');
}
// switch-case
String grade = 'A';
switch (grade) {
case 'A':
print('优秀');
break;
case 'B':
print('良好');
break;
case 'C':
print('及格');
break;
default:
print('不及格');
}
循环语句
// for 循环
for (int i = 0; i < 5; i++) {
print(i);
}
// for-in 循环
var fruits = ['苹果', '香蕉', '橙子'];
for (var fruit in fruits) {
print(fruit);
}
// while 循环
int count = 0;
while (count < 5) {
print(count);
count++;
}
// do-while 循环
int num = 0;
do {
print(num);
num++;
} while (num < 5);
// break 和 continue
for (int i = 0; i < 10; i++) {
if (i == 3) continue; // 跳过当前迭代
if (i == 7) break; // 退出循环
print(i); // 输出: 0, 1, 2, 4, 5, 6
}
函数
基本语法
// 基本函数
int add(int a, int b) {
return a + b;
}
// 箭头函数(单表达式)
int multiply(int a, int b) => a * b;
// 可选参数
String greet(String name, [String greeting = '你好']) {
return '$greeting,$name!';
}
print(greet('张三')); // 你好,张三!
print(greet('李四', '欢迎')); // 欢迎,李四!
// 命名参数
void printUser({required String name, int age = 18, String? city}) {
print('姓名:$name,年龄:$age,城市:${city ?? "未知"}');
}
printUser(name: '张三', age: 25, city: '北京');
printUser(name: '李四'); // 使用默认值
// 函数作为参数
void forEach(List<int> list, void Function(int) action) {
for (var item in list) {
action(item);
}
}
forEach([1, 2, 3], (n) => print(n));
// 匿名函数
var square = (int x) => x * x;
print(square(5)); // 25
闭包
// 闭包示例
Function makeCounter() {
int count = 0;
return () {
count++;
return count;
};
}
var counter = makeCounter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3
类和面向对象
定义类
class Person {
// 实例变量
String name;
int age;
// 构造函数
Person(this.name, this.age);
// 命名构造函数
Person.guest() : name = '访客', age = 0;
// 方法
void sayHello() {
print('你好,我叫$name,今年$age岁');
}
// 重写 toString
@override
String toString() => 'Person(name: $name, age: $age)';
}
// 使用类
var person = Person('张三', 25);
person.sayHello();
print(person);
var guest = Person.guest();
print(guest);
继承
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name 发出声音');
}
}
class Dog extends Animal {
String breed;
Dog(String name, this.breed) : super(name);
@override
void speak() {
print('$name 汪汪叫');
}
void fetch() {
print('$name 正在捡球');
}
}
var dog = Dog('旺财', '金毛');
dog.speak(); // 旺财 汪汪叫
dog.fetch(); // 旺财正在捡球
抽象类和接口
// 抽象类
abstract class Shape {
double get area;
double get perimeter;
void describe() {
print('面积:$area,周长:$perimeter');
}
}
// 实现抽象类
class Circle extends Shape {
double radius;
Circle(this.radius);
@override
double get area => 3.14159 * radius * radius;
@override
double get perimeter => 2 * 3.14159 * radius;
}
class Rectangle extends Shape {
double width, height;
Rectangle(this.width, this.height);
@override
double get area => width * height;
@override
double get perimeter => 2 * (width + height);
}
// 使用
var circle = Circle(5);
circle.describe();
var rect = Rectangle(4, 6);
rect.describe();
Mixin
Mixin 用于在多个类层次结构中复用代码:
mixin Swimmable {
void swim() {
print('正在游泳');
}
}
mixin Flyable {
void fly() {
print('正在飞行');
}
}
class Duck extends Animal with Swimmable, Flyable {
Duck(String name) : super(name);
}
var duck = Duck('唐老鸭');
duck.swim(); // 正在游泳
duck.fly(); // 正在飞行
Getter 和 Setter
class Temperature {
double _celsius; // 私有变量(以 _ 开头)
Temperature(this._celsius);
// Getter
double get fahrenheit => _celsius * 9 / 5 + 32;
// Setter
set fahrenheit(double value) {
_celsius = (value - 32) * 5 / 9;
}
double get celsius => _celsius;
set celsius(double value) => _celsius = value;
}
var temp = Temperature(100);
print(temp.fahrenheit); // 212.0
temp.fahrenheit = 32;
print(temp.celsius); // 0.0
异步编程
Future
Future 表示一个异步操作的结果:
// 模拟异步操作
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return '获取的数据';
}
// 使用 async/await
void getData() async {
print('开始获取数据...');
String data = await fetchData();
print('获取到:$data');
}
// 使用 then
fetchData().then((data) {
print('获取到:$data');
}).catchError((error) {
print('错误:$error');
});
// Future 链式调用
fetchData()
.then((data) => data.toUpperCase())
.then((upper) => print(upper))
.catchError((error) => print(error));
Stream
Stream 表示一系列异步事件:
// 创建 Stream
Stream<int> countStream() async* {
for (int i = 1; i <= 5; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
// 使用 Stream
void listenToStream() async {
await for (var count in countStream()) {
print(count);
}
}
// Stream 方法
countStream()
.where((n) => n % 2 == 0) // 过滤
.map((n) => n * n) // 映射
.listen((n) => print(n)); // 监听
异常处理
// 抛出异常
void validateAge(int age) {
if (age < 0) {
throw FormatException('年龄不能为负数');
}
if (age > 150) {
throw Exception('年龄不合理');
}
}
// 捕获异常
try {
validateAge(-5);
} on FormatException catch (e) {
print('格式错误:$e');
} on Exception catch (e) {
print('异常:$e');
} catch (e) {
print('未知错误:$e');
} finally {
print('清理工作');
}
泛型
// 泛型类
class Cache<T> {
final Map<String, T> _cache = {};
T? get(String key) => _cache[key];
void set(String key, T value) {
_cache[key] = value;
}
}
// 使用泛型
var stringCache = Cache<String>();
stringCache.set('name', '张三');
print(stringCache.get('name'));
var intCache = Cache<int>();
intCache.set('age', 25);
// 泛型函数
T first<T>(List<T> list) {
if (list.isEmpty) throw Exception('列表为空');
return list.first;
}
print(first([1, 2, 3])); // 1
print(first(['a', 'b', 'c'])); // a
枚举
// 基本枚举
enum Color { red, green, blue }
// 带属性的枚举(Dart 3.0+)
enum Status {
active('激活'),
inactive('未激活'),
pending('待处理');
final String description;
const Status(this.description);
}
// 使用枚举
Color color = Color.red;
print(color); // Color.red
print(color.index); // 0
print(Color.values); // [Color.red, Color.green, Color.blue]
Status status = Status.active;
print(status.description); // 激活
// switch 使用枚举
switch (status) {
case Status.active:
print('账户已激活');
break;
case Status.inactive:
print('账户未激活');
break;
case Status.pending:
print('账户待处理');
break;
}
小结
本章我们学习了:
- 变量和数据类型:var、final、const、数值、字符串、布尔、List、Set、Map
- 运算符:算术、比较、逻辑、条件运算符
- 控制流:if-else、switch、for、while 循环
- 函数:参数类型、箭头函数、闭包
- 面向对象:类、继承、抽象类、Mixin
- 异步编程:Future、async/await、Stream
- 异常处理:try-catch-finally
- 泛型和枚举
练习
- 创建一个
Student类,包含姓名、成绩属性,实现成绩等级判定 - 使用 Future 模拟网络请求,获取并处理数据
- 实现一个简单的缓存类,支持泛型
- 使用 Stream 实现一个倒计时功能
下一步
掌握 Dart 基础后,下一章我们将学习 Widget 基础,开始构建 Flutter 界面。