常见数据类型
Dart 提供如下核心内建类型,掌握每类的典型用法有助于编写可读且安全的代码:
int
/double
/num
:数值类型(整数、小数及二者统一的父类型)。String
:UTF-16 编码的字符串,支持插值与多行字符串。bool
:布尔值,仅包含true
与false
。List<T>
:有序集合(类似数组),支持可增长与固定长度两种形式。Set<T>
:元素唯一的集合,常用于去重或快速包含判断。Map<K, V>
:键值对集合,对应 JavaScript 中的对象或 Map。Runes
/Symbol
:分别用于处理 Unicode 码点与反射场景。dynamic
/Object
/Object?
:顶层类型,决定编译期与运行时的类型行为。
以下示例均基于空安全语法,并在每个小节保留旧笔记中的代码片段以供参考。
数字:int
、double
、num
void main() {
int hex = 0xDEADBEEF;
double pi = 3.1415926;
num score = 98; // num 可同时表示 int 和 double
score = 98.5;
// 字符串转数字
final parsed = int.parse('42');
final safeParsed = int.tryParse('forty-two'); // 返回 null
print(parsed); // 42
print(safeParsed ?? 'invalid');
}
dart
在空安全下,若需要允许数字为空,请使用 int?
或 double?
。
字符串:String
- 使用单引号或双引号声明;三重引号 (
'''
或"""
) 创建多行字符串。 - 插值语法:
'$value'
或'${expression}'
。 - 前缀
r
创建原始字符串,不处理转义字符。
void main() {
const language = 'Dart';
final desc = 'Hello, $language';
final multiLine = '''
Dart 支持多行字符串,
自动保留换行符。
''';
print(r"原始字符串中的 \n 不会被当作换行");
}
dart
布尔值:bool
bool
只有 true
和 false
两个值。局部变量需初始化或声明为可空:
void main() {
bool isLoading = false;
bool? isMounted; // 默认为 null
if (!isLoading && (isMounted ?? false)) {
print('Ready');
}
}
dart
列表(List)
列表是有序集合,常用字面量或构造函数创建:
void main() {
final names = <String>['Dash', 'Sparky'];
names.add('Sassy');
final fixed = List<int>.filled(3, 0); // 固定长度且初始值为 0
final unmodifiable = List.unmodifiable(names);
print(names.first); // Dash
print(names.where((name) => name.startsWith('S')).toList());
}
dart
集合(Set)
集合用于存储不重复元素,字面量使用 {}
:
final tags = <String>{'flutter', 'dart'};
tags.add('null-safety');
tags.add('flutter'); // 不会重复添加
dart
映射(Map)
final scores = <String, int>{
'Alice': 92,
'Bob': 85,
};
scores['Alice'] = 93;
print(scores.containsKey('Carol')); // false
dart
迭代 Map 时可以使用 entries
:
for (final entry in scores.entries) {
print('${entry.key}: ${entry.value}');
}
dart
Runes 与 Symbol
- Runes:处理 Unicode 码点,可通过
runes
属性或String.fromCharCodes
构造。 - Symbol:用于反射等场景,使用
#name
声明;在大多数业务代码中较少使用。
void main() {
const smile = '\u{1F600}';
print(smile); // 😀
const symbol = #myMethod;
print(symbol); // Symbol("myMethod")
}
dart
类型判断与转换
- 使用
is
/is!
做类型判断; as
进行类型转换(需确保运行时类型安全,或使用as?
在 Dart 3.12+ 中获得可空结果)。
void handle(dynamic value) {
if (value is String) {
print(value.toUpperCase());
} else if (value is num) {
print(value.toDouble());
}
}
dart
掌握以上基础类型即可覆盖大部分日常开发需求,后续章节将继续探索操作符、控制流等语言特性。
示例扩展(保留原有示例并适配空安全)
List 初始化与常用方法
void main() {
// 指定长度的 List 需要填充值
var names = List<String?>.filled(0, null, growable = true);
print(names.length); // 0
var fixedLength = List<int>.filled(2, 0);
print(fixedLength.length); // 2
// List<Object> 可以存放不同类型
var mixed = <Object?>[];
mixed.addAll(['toimc', 12, 11.0]);
print(mixed.runtimeType); // List<Object?>
const readOnly = [1, 2, 3];
// readOnly.add(4); // ❌: 常量列表不可修改
final users = <User>[
User('toimc', 23),
User('小方', 61),
User('小李', 48),
];
users.sort((a, b) => b.age.compareTo(a.age));
users.forEach((u) => print('${u.name}${u.age}'));
final filtered = users.where((u) => u.age == 23);
print(filtered.isEmpty);
print(users.isNotEmpty);
print('第一个元素: ${users.first.name}');
}
class User {
final String name;
final int age;
User(this.name, this.age);
}
dart
添加数据与遍历
void main() {
final names = <String>['小李', '小王', '小张'];
names.add('李四');
print(names.length); // 4
// growable = true 才能 add
final fixed = List<String>.filled(2, '', growable = false);
// fixed.add('新成员'); // ❌ Cannot add to a fixed-length list
final growableList = List<String>.empty(growable = true);
growableList.addAll(['A', 'B']);
// 遍历
for (var i = 0; i < names.length; i++) {
print('index $i -> ${names[i]}');
}
names.forEach((item) => print(item));
}
dart
Set 与 Map 补充
void main() {
final views = <String>{};
views.addAll({'首页', '发现', '发现'});
print(views.length); // 2
final info = <String, dynamic>{
'name': 'toimc',
'age': 18,
};
info['city'] = 'Shenzhen';
info.update('age', (value) => (value as int) + 1);
info.removeWhere((key, value) => value == null);
info.forEach((key, value) => print('$key -> $value'));
}
dart
↑