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
使用注意事项:
⚠️ 重要提醒:
-
整数溢出处理:
// Dart中的int在不同平台有不同范围 // Web平台:-2^53 到 2^53 // 其他平台:-2^63 到 2^63-1 // 检查平台限制 print('最大整数: ${double.maxFinite.toInt()}'); -
除法运算陷阱:
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
使用注意事项:
⚠️ 重要提醒:
-
浮点数精度问题:
// ❌ 浮点数比较陷阱 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 -
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"
字符串使用注意事项:
⚠️ 重要提醒:
-
字符串不可变性:
String original = "Hello"; String modified = original.toUpperCase(); // original仍然是"Hello",toUpperCase()返回新字符串 print(original); // "Hello" print(modified); // "HELLO" -
Unicode和编码问题:
String emoji = "👋🌍"; print(emoji.length); // 4 (不是2!) print(emoji.runes.length); // 2 (正确的字符数) // 正确遍历Unicode字符 for (int rune in emoji.runes) { print(String.fromCharCode(rune)); } -
字符串性能优化:
// ❌ 效率低的字符串拼接 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
布尔类型注意事项:
⚠️ 重要提醒:
- 真值判断:
// 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使用注意事项:
⚠️ 重要提醒:
-
键的相等性和哈希:
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,因为正确实现了相等性 -
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>(); -
空安全和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. 集合类型性能对比
| 操作 | List | Set | Map |
|---|---|---|---|
| 访问 | 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提供了丰富而强大的数据类型系统,理解和正确使用这些类型对于编写高效、安全的代码至关重要:
- 基础类型:掌握int、double、String、bool的特性和使用场景
- 集合类型:根据需求选择List、Set、Map的合适实现
- 类型系统:充分利用空安全、泛型和类型推断
- 性能考虑:了解不同类型的性能特点,选择合适的数据结构
- 最佳实践:遵循Dart社区的编码规范和最佳实践
通过深入理解Dart的数据类型系统,可以编写出更加健壮、高效和可维护的代码。
本文档基于Dart 3.x版本整理,涵盖了核心数据类型的详细使用方法和最佳实践。