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. 开发实践建议

  1. 优先选择类型推断,必要处显式声明
  2. 公共API必须显式类型注解
  3. 使用final声明不会修改的变量
  4. 集合操作注意类型参数指定
  5. 谨慎处理dynamic类型,尽量缩小作用域

8. 总结提升

通过本文的系统学习,我们深入掌握了Dart变量与数据类型的核心要点。记住:

  • 类型系统是Dart安全的基石
  • 合理使用类型推断提升开发效率
  • 类型注释是代码文档的重要部分
  • 空安全机制需要贯穿开发始终

建议将本文示例代码在DartPad中实际运行,观察类型变化和运行时行为。掌握这些基础知识后,可以进一步学习泛型、异步编程等高级主题,构建更健壮的Dart应用程序。