Dart 数据类型详细总结

92 阅读12分钟

Dart 数据类型详细总结

基于Dart官方API文档与实践经验整理

目录

概述

Dart是一种强类型的编程语言,提供了丰富的内置数据类型。理解这些数据类型的特性、使用场景和性能特点对于编写高效的Dart代码至关重要。

Dart类型系统的核心特性

  • 静态类型检查:编译时进行类型检查
  • 类型推断:自动推断变量类型
  • 空安全:null safety机制防止空指针异常
  • 泛型支持:支持参数化类型
  • 类型层次结构:所有类型都继承自Object

基础数据类型

1. 数值类型 (Numbers)

int - 整数类型
// 基本使用
int age = 25;
int hexValue = 0xFF; // 255
int binaryValue = 0b1010; // 10

// 常用属性和方法
print(age.isEven);        // false
print(age.isOdd);         // true
print(age.sign);          // 1 (正数)
print(age.abs());         // 25
print((-age).abs());      // 25

// 类型转换
String ageStr = age.toString();
double ageDouble = age.toDouble();

// 进制转换
print(255.toRadixString(16)); // "ff"
print(255.toRadixString(2));  // "11111111"

// 解析字符串
int parsed = int.parse('123');
int? tryParsed = int.tryParse('abc'); // null

使用注意事项:

⚠️ 重要提醒:

  1. 整数溢出处理

    // Dart中的int在不同平台有不同范围
    // Web平台:-2^53 到 2^53
    // 其他平台:-2^63 到 2^63-1
    
    // 检查平台限制
    print('最大整数: ${double.maxFinite.toInt()}');
    
  2. 除法运算陷阱

    int a = 5;
    int b = 2;
    
    // ❌ 这会返回double类型
    var result1 = a / b; // 2.5 (double)
    
    // ✅ 整数除法
    var result2 = a ~/ b; // 2 (int)
    var remainder = a % b; // 1 (int)
    
double - 双精度浮点数
// 基本使用
double price = 99.99;
double scientific = 1.5e3; // 1500.0
double infinity = double.infinity;
double nan = double.nan;

// 常用属性和方法
print(price.isFinite);     // true
print(price.isInfinite);   // false
print(price.isNaN);        // false
print(price.sign);         // 1.0
print(price.floor());      // 99
print(price.ceil());       // 100
print(price.round());      // 100

// 精度控制
print(price.toStringAsFixed(1)); // "100.0"
print(price.toStringAsPrecision(4)); // "100.0"

// 特殊值处理
print(double.infinity == double.infinity); // true
print(double.nan == double.nan); // false!
print(double.nan.isNaN); // true

使用注意事项:

⚠️ 重要提醒:

  1. 浮点数精度问题

    // ❌ 浮点数比较陷阱
    double a = 0.1 + 0.2;
    double b = 0.3;
    print(a == b); // false!
    print(a); // 0.30000000000000004
    
    // ✅ 正确的浮点数比较
    bool isEqual(double a, double b, {double epsilon = 1e-10}) {
      return (a - b).abs() < epsilon;
    }
    print(isEqual(a, b)); // true
    
  2. NaN的特殊行为

    double nan = double.nan;
    
    // NaN不等于任何值,包括自己
    print(nan == nan); // false
    print(nan < 5);    // false
    print(nan > 5);    // false
    
    // 检查NaN
    print(nan.isNaN);  // true
    
num - 数值基类
// num是int和double的父类
num getValue(bool useInt) {
  return useInt ? 42 : 3.14;
}

num value = getValue(true);
print(value.runtimeType); // int

// 通用数值操作
num a = 10;
num b = 3.5;
print(a + b);    // 13.5
print(a.compareTo(b)); // 1

2. 字符串类型 (String)

// 基本创建
String name = 'Alice';
String greeting = "Hello";
String multiline = '''
这是一个
多行字符串
''';

// 字符串插值
int age = 25;
String message = '我的名字是$name,今年$age岁';
String calculation = '5 + 3 = ${5 + 3}';

// 常用属性和方法
print(name.length);           // 5
print(name.isEmpty);          // false
print(name.isNotEmpty);       // true
print(name.codeUnits);        // [65, 108, 105, 99, 101]

// 字符串操作
print(name.toUpperCase());    // "ALICE"
print(name.toLowerCase());    // "alice"
print(name.substring(1, 3));  // "li"
print(name.contains('li'));   // true
print(name.startsWith('Al')); // true
print(name.endsWith('ce'));   // true
print(name.indexOf('i'));     // 2

// 字符串分割和连接
String sentence = "Hello world Dart";
List<String> words = sentence.split(' ');
String joined = words.join('-');
print(joined); // "Hello-world-Dart"

// 字符串修剪
String padded = "  hello world  ";
print(padded.trim());      // "hello world"
print(padded.trimLeft());  // "hello world  "
print(padded.trimRight()); // "  hello world"

// 字符串替换
String text = "Hello world";
print(text.replaceAll('l', 'L')); // "HeLLo worLd"
print(text.replaceFirst('l', 'L')); // "HeLlo world"

字符串使用注意事项:

⚠️ 重要提醒:

  1. 字符串不可变性

    String original = "Hello";
    String modified = original.toUpperCase();
    
    // original仍然是"Hello",toUpperCase()返回新字符串
    print(original); // "Hello"
    print(modified); // "HELLO"
    
  2. Unicode和编码问题

    String emoji = "👋🌍";
    print(emoji.length); // 4 (不是2!)
    print(emoji.runes.length); // 2 (正确的字符数)
    
    // 正确遍历Unicode字符
    for (int rune in emoji.runes) {
      print(String.fromCharCode(rune));
    }
    
  3. 字符串性能优化

    // ❌ 效率低的字符串拼接
    String result = '';
    for (int i = 0; i < 1000; i++) {
      result += 'item$i '; // 每次都创建新字符串
    }
    
    // ✅ 使用StringBuffer优化
    StringBuffer buffer = StringBuffer();
    for (int i = 0; i < 1000; i++) {
      buffer.write('item$i ');
    }
    String efficient = buffer.toString();
    

3. 布尔类型 (bool)

// 基本使用
bool isActive = true;
bool isCompleted = false;

// 逻辑运算
bool result1 = true && false;  // false
bool result2 = true || false;  // true
bool result3 = !true;          // false

// 比较运算返回bool
bool isEqual = (5 == 5);       // true
bool isGreater = (10 > 5);     // true

// 条件判断
if (isActive) {
  print('激活状态');
}

// 三元运算符
String status = isActive ? '激活' : '未激活';

// 空安全中的bool?
bool? nullable;
print(nullable ?? false); // false

布尔类型注意事项:

⚠️ 重要提醒:

  1. 真值判断
    // Dart中只有true是真值,其他都是假值
    if (true) { } // ✅
    // if (1) { }    // ❌ 编译错误
    // if ("hello") { } // ❌ 编译错误
    
    // 正确的非空检查
    String? text;
    if (text != null && text.isNotEmpty) {
      print(text);
    }
    

4. 符号类型 (Symbol)

// Symbol用于表示操作符或标识符
Symbol sym1 = #hello;
Symbol sym2 = Symbol('world');

// 主要用于反射和元编程
print(sym1); // Symbol("hello")
print(sym1 == #hello); // true

// 在Flutter中用于Hero标签等
// Hero(tag: #heroTag, child: widget)

集合数据类型

1. List - 列表

详细内容请参考:Dart List API 详细总结

核心特性:

  • 有序集合,允许重复元素
  • 支持索引访问
  • 动态大小(可增长列表)
  • 泛型支持
// 基本使用示例
List<String> fruits = ['苹果', '香蕉', '橙子'];
List<int> numbers = [1, 2, 3, 4, 5];

// 常用操作
fruits.add('葡萄');
fruits.removeAt(0);
fruits.insert(1, '草莓');

// 函数式操作
var doubled = numbers.map((n) => n * 2).toList();
var evens = numbers.where((n) => n % 2 == 0).toList();

2. Set - 集合

详细内容请参考:Dart Set API 详细总结

核心特性:

  • 无重复元素
  • 高效的查找操作
  • 支持集合运算
  • 无序(HashSet)或有序(LinkedHashSet)
// 基本使用示例
Set<String> colors = {'红', '绿', '蓝'};
Set<int> numbers = {1, 2, 3, 4, 5};

// 去重功能
Set<int> unique = [1, 2, 2, 3, 3].toSet(); // {1, 2, 3}

// 集合运算
Set<int> set1 = {1, 2, 3};
Set<int> set2 = {3, 4, 5};
Set<int> union = set1.union(set2);         // {1, 2, 3, 4, 5}
Set<int> intersection = set1.intersection(set2); // {3}

3. Map - 映射

// 基本创建
Map<String, int> scores = {
  'Alice': 95,
  'Bob': 87,
  'Charlie': 92
};

// 空Map
Map<String, int> emptyMap = <String, int>{};
Map<String, int> emptyMap2 = Map<String, int>();

// 动态类型Map
Map<dynamic, dynamic> flexible = {
  'name': 'Alice',
  'age': 25,
  1: 'first',
  true: 'boolean key'
};

// 基本操作
print(scores['Alice']);        // 95
scores['David'] = 88;          // 添加新键值对
scores.remove('Bob');          // 删除键值对
scores.clear();                // 清空Map

// 常用属性
print(scores.length);          // Map大小
print(scores.isEmpty);         // 是否为空
print(scores.isNotEmpty);      // 是否非空
print(scores.keys);            // 所有键
print(scores.values);          // 所有值
print(scores.entries);         // 所有键值对

// 查询操作
print(scores.containsKey('Alice'));    // 是否包含键
print(scores.containsValue(95));       // 是否包含值

// 安全访问
int? aliceScore = scores['Alice'];     // 可能为null
int safeScore = scores['Alice'] ?? 0;  // 提供默认值

// 批量操作
scores.addAll({'Eve': 91, 'Frank': 89});
scores.removeWhere((key, value) => value < 90);

// 转换操作
Map<String, String> stringScores = scores.map(
  (key, value) => MapEntry(key, value.toString())
);

// 遍历Map
scores.forEach((key, value) {
  print('$key: $value');
});

for (var entry in scores.entries) {
  print('${entry.key}: ${entry.value}');
}

for (var key in scores.keys) {
  print('$key: ${scores[key]}');
}

Map使用注意事项:

⚠️ 重要提醒:

  1. 键的相等性和哈希

    class Person {
      String name;
      Person(this.name);
      
      // ✅ 必须同时重写==和hashCode
      @override
      bool operator ==(Object other) =>
          other is Person && other.name == name;
      
      @override
      int get hashCode => name.hashCode;
    }
    
    Map<Person, int> ages = {
      Person('Alice'): 25,
    };
    
    print(ages[Person('Alice')]); // 25,因为正确实现了相等性
    
  2. Map的不同实现

    import 'dart:collection';
    
    // HashMap - 无序,最快的访问速度
    Map<String, int> hashMap = HashMap<String, int>();
    
    // LinkedHashMap - 保持插入顺序(默认实现)
    Map<String, int> linkedMap = <String, int>{};
    
    // SplayTreeMap - 自动排序
    SplayTreeMap<String, int> sortedMap = SplayTreeMap<String, int>();
    
  3. 空安全和Map访问

    Map<String, String?> nullableMap = {'key': null};
    
    // 区分键不存在和值为null
    print(nullableMap['key']);        // null (值为null)
    print(nullableMap['missing']);    // null (键不存在)
    print(nullableMap.containsKey('key'));     // true
    print(nullableMap.containsKey('missing')); // false
    

4. Iterable - 可迭代对象

详细内容请参考:iterable_summary.dart

核心特性:

  • 所有集合类型的基类
  • 惰性求值
  • 支持链式操作
  • 函数式编程风格
// Iterable是抽象基类
Iterable<int> numbers = [1, 2, 3, 4, 5];

// 惰性操作
var result = numbers
    .where((n) => n % 2 == 0)
    .map((n) => n * n)
    .take(2);

print(result.toList()); // [4, 16]

其他重要数据类型

1. DateTime - 日期时间

// 创建DateTime
DateTime now = DateTime.now();
DateTime specific = DateTime(2024, 1, 15, 14, 30);
DateTime utc = DateTime.utc(2024, 1, 15);
DateTime parsed = DateTime.parse('2024-01-15 14:30:00');

// 常用属性
print(now.year);          // 年
print(now.month);         // 月
print(now.day);           // 日
print(now.hour);          // 时
print(now.minute);        // 分
print(now.second);        // 秒
print(now.millisecond);   // 毫秒
print(now.weekday);       // 星期几(1-7)

// 时间计算
DateTime tomorrow = now.add(Duration(days: 1));
DateTime lastWeek = now.subtract(Duration(days: 7));
Duration difference = tomorrow.difference(now);

// 时间比较
print(now.isBefore(tomorrow));    // true
print(now.isAfter(lastWeek));     // true
print(now.isAtSameMomentAs(now)); // true

// 格式化
print(now.toString());                    // 2024-01-15 14:30:00.000
print(now.toIso8601String());            // 2024-01-15T14:30:00.000
print(now.toLocal());                     // 转为本地时间
print(now.toUtc());                       // 转为UTC时间

// 时间戳
int timestamp = now.millisecondsSinceEpoch;
DateTime fromTimestamp = DateTime.fromMillisecondsSinceEpoch(timestamp);

2. Duration - 时间段

// 创建Duration
Duration oneHour = Duration(hours: 1);
Duration mixed = Duration(days: 1, hours: 2, minutes: 30);
Duration fromMicroseconds = Duration(microseconds: 1000000);

// 常用属性
print(oneHour.inHours);        // 1
print(oneHour.inMinutes);      // 60
print(oneHour.inSeconds);      // 3600
print(oneHour.inMilliseconds); // 3600000

// 时间段运算
Duration total = oneHour + Duration(minutes: 30);
Duration remaining = Duration(hours: 2) - oneHour;

// 比较
print(oneHour > Duration(minutes: 30)); // true
print(oneHour.compareTo(Duration(hours: 2))); // -1

3. RegExp - 正则表达式

// 创建正则表达式
RegExp emailPattern = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
RegExp phonePattern = RegExp(r'^\d{3}-\d{3}-\d{4}$');

// 匹配检查
String email = 'user@example.com';
print(emailPattern.hasMatch(email)); // true

// 查找匹配
String text = 'Call me at 123-456-7890 or 987-654-3210';
Iterable<Match> matches = phonePattern.allMatches(text);
for (Match match in matches) {
  print('Found: ${match.group(0)}');
}

// 替换
String censored = text.replaceAll(phonePattern, 'XXX-XXX-XXXX');
print(censored); // Call me at XXX-XXX-XXXX or XXX-XXX-XXXX

// 分组捕获
RegExp namePattern = RegExp(r'(\w+)\s+(\w+)');
Match? match = namePattern.firstMatch('John Doe');
if (match != null) {
  print('First: ${match.group(1)}');  // John
  print('Last: ${match.group(2)}');   // Doe
  print('Full: ${match.group(0)}');   // John Doe
}

4. Runes - Unicode字符

// Runes表示字符串的UTF-32代码点
String text = '👋🌍 Hello';
Runes runes = text.runes;

print('字符串长度: ${text.length}');      // 9
print('实际字符数: ${runes.length}');      // 8

// 遍历Unicode字符
for (int rune in runes) {
  print('${String.fromCharCode(rune)} (U+${rune.toRadixString(16).toUpperCase()})');
}

// 构建Unicode字符串
String fromRunes = String.fromCharCodes([0x1F44B, 0x1F30D]); // 👋🌍
print(fromRunes);

5. Uri - 统一资源标识符

// 解析URI
Uri uri = Uri.parse('https://example.com:8080/path?query=value#fragment');

print('协议: ${uri.scheme}');      // https
print('主机: ${uri.host}');        // example.com
print('端口: ${uri.port}');        // 8080
print('路径: ${uri.path}');        // /path
print('查询: ${uri.query}');       // query=value
print('片段: ${uri.fragment}');    // fragment

// 构建URI
Uri built = Uri(
  scheme: 'https',
  host: 'api.example.com',
  path: '/users/123',
  queryParameters: {'format': 'json', 'include': 'profile'}
);
print(built.toString()); // https://api.example.com/users/123?format=json&include=profile

// URI编码
String encoded = Uri.encodeComponent('Hello World!');
String decoded = Uri.decodeComponent(encoded);
print('编码: $encoded'); // Hello%20World!
print('解码: $decoded'); // Hello World!

类型系统特性

1. 空安全 (Null Safety)

// 可空类型
String? nullableString;
int? nullableInt;

// 非空类型
String nonNullString = 'Hello';
// String nonNull = null; // 编译错误

// 空安全操作符
String? name;
int length = name?.length ?? 0;           // 空安全访问
name ??= 'Default';                       // 空赋值
String definitelyString = name!;          // 非空断言

// 空安全检查
if (name != null) {
  // 类型提升,name在此作用域内被视为非空
  print(name.length);
}

// late关键字
late String lateString;
late final String lateFinalString;

void initializeLateVars() {
  lateString = 'Initialized';
  lateFinalString = 'Final value';
}

2. 泛型 (Generics)

// 泛型类
class Box<T> {
  T value;
  Box(this.value);
  
  void setValue(T newValue) {
    value = newValue;
  }
  
  T getValue() => value;
}

// 使用泛型
Box<String> stringBox = Box('Hello');
Box<int> intBox = Box(42);

// 泛型约束
class NumberBox<T extends num> {
  T value;
  NumberBox(this.value);
  
  T add(T other) => (value + other) as T;
}

// 泛型函数
T identity<T>(T value) => value;
List<T> createList<T>(T value, int count) {
  return List.filled(count, value);
}

// 使用
String result = identity<String>('test');
List<int> numbers = createList<int>(0, 5);

3. 类型别名 (Type Aliases)

// 函数类型别名
typedef IntFunction = int Function(int);
typedef StringProcessor = String Function(String input);

// 使用类型别名
IntFunction doubler = (x) => x * 2;
StringProcessor upperCase = (s) => s.toUpperCase();

// 泛型类型别名
typedef Mapper<T, R> = R Function(T);
typedef Predicate<T> = bool Function(T);

Mapper<String, int> stringLength = (s) => s.length;
Predicate<int> isEven = (n) => n % 2 == 0;

// 复杂类型别名
typedef JsonMap = Map<String, dynamic>;
typedef UserData = Map<String, Object?>;

JsonMap parseJson(String jsonString) {
  // JSON解析逻辑
  return <String, dynamic>{};
}

4. 类型检查和转换

// 类型检查 (is)
dynamic value = 'Hello';
if (value is String) {
  print('是字符串: ${value.length}'); // 类型提升
}

// 类型转换 (as)
dynamic number = 42;
int intValue = number as int;

// 安全类型转换
int? safeInt = number is int ? number : null;

// 类型模式匹配 (Dart 3.0+)
switch (value) {
  case int i when i > 0:
    print('正整数: $i');
  case String s when s.isNotEmpty:
    print('非空字符串: $s');
  case List<int> list:
    print('整数列表: $list');
  default:
    print('其他类型');
}

数据类型选择指南

1. 数值类型选择

// 整数运算,明确不会有小数
int count = 10;
int userId = 12345;

// 需要小数精度
double price = 99.99;
double percentage = 0.15;

// 不确定是整数还是小数
num getValue() => Random().nextBool() ? 42 : 3.14;

// 货币计算(避免浮点精度问题)
class Money {
  final int _cents; // 以分为单位存储
  
  Money.fromDollars(double dollars) : _cents = (dollars * 100).round();
  Money.fromCents(int cents) : _cents = cents;
  
  double get dollars => _cents / 100.0;
  int get cents => _cents;
  
  Money operator +(Money other) => Money.fromCents(_cents + other._cents);
}

2. 字符串 vs 符号

// 普通文本数据
String userName = 'alice';
String message = 'Hello World';

// 标识符或常量(不会改变的标识)
Symbol methodName = #toString;
Symbol eventType = #onClick;

// 枚举替代符号(更类型安全)
enum EventType { click, hover, focus }

3. 集合类型选择

// 需要索引访问和顺序
List<String> menuItems = ['首页', '产品', '关于'];

// 需要去重和快速查找
Set<String> uniqueIds = {'user1', 'user2', 'user3'};

// 键值对关联
Map<String, User> userCache = {'123': User('Alice')};

// 只读数据
const List<String> weekdays = ['周一', '周二', '周三', '周四', '周五'];

4. 可空性选择

// 明确不会为null
String name = 'Alice';
int age = 25;

// 可能为null
String? middleName;
int? score;

// 延迟初始化
late String configValue;

// 最终值(只能赋值一次)
final String appName = 'MyApp';
late final String apiKey; // 延迟初始化的final

性能对比

1. 集合类型性能对比

操作ListSetMap
访问O(1) 索引访问-O(1) 键访问
查找O(n) 线性查找O(1) 哈希查找O(1) 键查找
插入O(1) 末尾,O(n) 中间O(1) 哈希插入O(1) 键值插入
删除O(n) 按值,O(1) 末尾O(1) 哈希删除O(1) 键删除

2. 字符串操作性能

// 性能测试示例
void stringPerformanceTest() {
  Stopwatch sw = Stopwatch();
  
  // ❌ 低效的字符串拼接
  sw.start();
  String result1 = '';
  for (int i = 0; i < 10000; i++) {
    result1 += 'item$i ';
  }
  sw.stop();
  print('字符串拼接: ${sw.elapsedMilliseconds}ms');
  
  // ✅ 高效的StringBuffer
  sw.reset();
  sw.start();
  StringBuffer buffer = StringBuffer();
  for (int i = 0; i < 10000; i++) {
    buffer.write('item$i ');
  }
  String result2 = buffer.toString();
  sw.stop();
  print('StringBuffer: ${sw.elapsedMilliseconds}ms');
}

3. 内存使用对比

// 内存效率对比
void memoryComparison() {
  // List vs Set内存使用
  List<int> list = List.generate(10000, (i) => i);
  Set<int> set = Set.from(list);
  
  print('List大小: ${list.length}');
  print('Set大小: ${set.length}');
  
  // Map vs List<List>内存使用
  Map<String, String> map = {
    for (int i = 0; i < 1000; i++) 'key$i': 'value$i'
  };
  
  List<List<String>> pairs = [
    for (int i = 0; i < 1000; i++) ['key$i', 'value$i']
  ];
}

最佳实践

1. 类型声明最佳实践

// ✅ 明确的类型声明
List<String> names = ['Alice', 'Bob'];
Map<String, int> scores = {'Alice': 95};

// ✅ 合理使用类型推断
var userName = 'Alice'; // 清楚是String
var userAge = 25;       // 清楚是int

// ❌ 过度使用dynamic
dynamic data = getData(); // 失去类型安全

// ✅ 使用泛型保持类型安全
T processData<T>(T data) {
  // 处理逻辑
  return data;
}

2. 空安全最佳实践

// ✅ 优先使用非空类型
String name = 'Alice';

// ✅ 合理使用可空类型
String? optionalName;

// ✅ 安全的空检查
if (optionalName != null) {
  print(optionalName.length); // 类型提升
}

// ✅ 使用空安全操作符
int length = optionalName?.length ?? 0;

// ❌ 过度使用非空断言
// print(optionalName!.length); // 可能抛出异常

3. 集合使用最佳实践

// ✅ 根据用途选择合适的集合
List<String> orderedItems = ['first', 'second', 'third'];
Set<String> uniqueItems = {'item1', 'item2'};
Map<String, dynamic> keyValuePairs = {'key': 'value'};

// ✅ 使用const优化性能
const List<String> constants = ['A', 'B', 'C'];

// ✅ 预分配大小(如果已知)
List<int> numbers = List.filled(100, 0);

// ✅ 使用适当的构造函数
List<int> generated = List.generate(10, (i) => i * i);
Set<String> fromList = {'a', 'b', 'c'}.toSet();

4. 性能优化最佳实践

// ✅ 缓存昂贵的计算
class ExpensiveCalculation {
  static final Map<String, int> _cache = {};
  
  static int calculate(String input) {
    return _cache.putIfAbsent(input, () {
      // 昂贵的计算
      return input.hashCode;
    });
  }
}

// ✅ 使用惰性初始化
class LazyResource {
  late final String _expensiveResource = _loadResource();
  
  String _loadResource() {
    // 昂贵的资源加载
    return 'loaded';
  }
  
  String get resource => _expensiveResource;
}

// ✅ 避免不必要的对象创建
class ObjectPool<T> {
  final List<T> _pool = [];
  final T Function() _factory;
  
  ObjectPool(this._factory);
  
  T acquire() {
    return _pool.isEmpty ? _factory() : _pool.removeLast();
  }
  
  void release(T object) {
    _pool.add(object);
  }
}

5. 错误处理最佳实践

// ✅ 使用异常处理
class DataProcessor {
  String processData(String input) {
    if (input.isEmpty) {
      throw ArgumentError('输入不能为空');
    }
    
    try {
      return input.toUpperCase();
    } catch (e) {
      throw ProcessingError('处理数据失败: $e');
    }
  }
}

// ✅ 自定义异常类
class ProcessingError extends Error {
  final String message;
  ProcessingError(this.message);
  
  @override
  String toString() => 'ProcessingError: $message';
}

// ✅ 使用Result模式处理错误
abstract class Result<T, E> {
  const Result();
}

class Success<T, E> extends Result<T, E> {
  final T value;
  const Success(this.value);
}

class Failure<T, E> extends Result<T, E> {
  final E error;
  const Failure(this.error);
}

总结

Dart提供了丰富而强大的数据类型系统,理解和正确使用这些类型对于编写高效、安全的代码至关重要:

  1. 基础类型:掌握int、double、String、bool的特性和使用场景
  2. 集合类型:根据需求选择List、Set、Map的合适实现
  3. 类型系统:充分利用空安全、泛型和类型推断
  4. 性能考虑:了解不同类型的性能特点,选择合适的数据结构
  5. 最佳实践:遵循Dart社区的编码规范和最佳实践

通过深入理解Dart的数据类型系统,可以编写出更加健壮、高效和可维护的代码。


本文档基于Dart 3.x版本整理,涵盖了核心数据类型的详细使用方法和最佳实践。