1. 变量声明的三种姿势
在Dart的世界里,声明变量就像选择交通工具:你可以坐公交(var)、开私家车(明确类型),或者选择环保出行(final/const)。让我们通过实际代码感受它们的区别:
// 示例1.1:灵活派var的使用
var weather = 'sunny'; // 自动推断为String类型
weather = 'rainy'; // 合法操作
// weather = 42; // 非法!类型不可更改
// 示例1.2:类型明确声明
double temperature = 36.5; // 显式声明为双精度浮点
temperature = 36.6; // 值可修改
// temperature = '37℃'; // 类型错误
// 示例1.3:常量双雄对比
final installTime = DateTime.now(); // 运行时确定值
const pi = 3.1415926; // 编译时常量
// const currentTime = DateTime.now(); // 编译报错!
应用场景建议:
- 局部变量优先使用var提升代码简洁性
- 类成员变量推荐显式类型声明增强可读性
- 配置参数使用const,运行时常量用final
2. 七大核心数据类型详解
2.1 数字类型双雄
int population = 1400000000; // 整数存储
double height = 1.75; // 浮点精度
var result = population / 100; // 自动转为double
print(result.runtimeType); // 输出:double
2.2 字符串的三种姿势
// 单行字符串
String greeting = 'Hello, Dart!';
// 多行字符串
String poem = '''
春眠不觉晓,
处处闻啼鸟。
''';
// 模板字符串
var version = 3.0;
print('Dart $version is awesome!'); // 输出:Dart 3.0 is awesome!
2.3 布尔值的正确打开方式
bool isRaining = true;
var hasLicense = false;
// 特别注意:Dart要求严格布尔判断
var count = 0;
// if (count) { ... } // 非法!必须明确布尔值
if (count > 0) { ... } // 正确写法
2.4 动态类型的使用哲学
dynamic flexibleVar = 'I can be anything';
flexibleVar = 2023; // 合法但需谨慎
flexibleVar = DateTime.now(); // 继续变身
// 安全访问技巧
if (flexibleVar is DateTime) {
print(flexibleVar.year); // 类型检查后安全使用
}
2.5 列表的七十二变
// 基础列表
List<String> colors = ['red', 'green', 'blue'];
// 类型推断写法
var primes = [2, 3, 5, 7]; // 推断为List<int>
// 扩展运算符妙用
var allNumbers = [...primes, 11, 13];
// 空安全操作
var emptyList = <String>[];
print(emptyList.firstOrNull ?? '列表为空'); // 使用空安全语法
2.6 字典的多种构造方式
// 显式类型声明
Map<String, dynamic> userProfile = {
'name': '李华',
'age': 28,
'isVip': true
};
// 类型推断写法
var product = {
'id': 'P1001',
'price': 299.99,
'inStock': true
};
// 空安全访问
print(userProfile['address']?.toString() ?? '地址未填写');
2.7 符号类型的特殊用途
Symbol libName = #json_serializable; // 表示库标识符
var method = #toString; // 方法符号
// 主要用于反射等高级场景
3. 类型推断的智能魔法
Dart的类型推断引擎就像经验丰富的侦探,总能从代码线索中找出正确类型:
var message = 'Welcome'; // 推断为String
var matrix = [[1,2], [3,4]]; // List<List<int>>
// 集合类型推断
var coordinates = {'lat': 39.9, 'lng': 116.4}; // Map<String, double>
// 函数返回类型推断
sum(a, b) => a + b; // 推断返回类型为dynamic(存在隐患!)
最佳实践:
- 局部变量可依赖类型推断
- 函数参数和返回值建议显式声明
- 复杂表达式适当添加类型注解
4. 类型转换的四大法门
4.1 安全转换操作符
var someValue = '123';
var number = int.tryParse(someValue) ?? 0; // 安全转换
4.2 强制类型断言
dynamic userId = 'U1001';
String id = userId as String; // 运行时类型检查
// var error = userId as int; // 抛出CastError
4.3 类型判断与转换
void handleValue(dynamic value) {
if (value is Map<String, dynamic>) {
print(value['key']); // 安全访问
}
}
4.4 泛型集合转换
var dynamicList = ['text', 123, true];
var intList = dynamicList.whereType<int>().toList(); // [123]
5. 实战应用场景分析
5.1 Flutter状态管理
class CounterState {
final int count; // 不可变状态
final String lastUpdated; // 时间戳
const CounterState(this.count, this.lastUpdated);
}
5.2 JSON数据处理
Map<String, dynamic> parseUser(String jsonStr) {
var data = jsonDecode(jsonStr);
return {
'id': data['id'] as int,
'name': data['name'] ?? '未知用户',
'vipLevel': (data['vip'] as num?)?.toInt() ?? 0
};
}
5.3 函数式编程应用
var numbers = [1, 2, 3, 4];
var squared = numbers.map((n) => n * n).toList(); // [1,4,9,16]
6. 技术特性深度解析
优势亮点:
- 健全的空安全体系
- 强大的类型推断能力
- 灵活的动态类型支持
- 高效的JIT/AOT编译支持
潜在注意事项:
- 避免过度使用dynamic类型
- 注意类型推断的边界情况
- 正确处理平台特定类型(如JS互操作)
关联技术:
- Null Safety机制:通过?、!、late等操作符提升代码安全性
- 泛型系统:在集合类型中广泛应用的类型参数化
- 类型别名:使用typedef创建更语义化的类型声明
7. 开发实践建议
- 优先选择类型推断,必要处显式声明
- 公共API必须显式类型注解
- 使用final声明不会修改的变量
- 集合操作注意类型参数指定
- 谨慎处理dynamic类型,尽量缩小作用域
8. 总结提升
通过本文的系统学习,我们深入掌握了Dart变量与数据类型的核心要点。记住:
- 类型系统是Dart安全的基石
- 合理使用类型推断提升开发效率
- 类型注释是代码文档的重要部分
- 空安全机制需要贯穿开发始终
建议将本文示例代码在DartPad中实际运行,观察类型变化和运行时行为。掌握这些基础知识后,可以进一步学习泛型、异步编程等高级主题,构建更健壮的Dart应用程序。