Flutter 数据类型总结
Flutter 数据类型总结
Flutter 使用 Dart 语言,Dart 是一门强类型语言,但支持类型推断。本文将全面总结 Flutter/Dart 中的数据类型。
基本数据类型
1. 数字类型 (Numbers)
Dart 中的数字类型有两种:
int - 整数类型
int age = 25;
int count = -10;
int hexValue = 0xFF; // 十六进制
int binaryValue = 0b1010; // 二进制
double - 浮点数类型
double price = 99.99;
double temperature = -5.5;
double scientific = 1.2e5; // 科学计数法,等于 120000.0
num - 数字基类
num 是 int 和 double 的父类,可以同时表示整数和浮点数:
num number1 = 10; // 可以是 int
num number2 = 10.5; // 也可以是 double
2. 字符串类型 (String)
字符串可以用单引号或双引号定义,支持多行字符串和字符串插值:
String name = 'Flutter';
String message = "Hello, $name"; // 字符串插值
String multiLine = '''
这是多行
字符串
''';
// 字符串拼接
String fullName = 'John' + ' ' + 'Doe';
String greeting = 'Hello, ${name.toUpperCase()}'; // 表达式插值
3. 布尔类型 (bool)
Dart 中的布尔类型只有两个值:true 和 false:
bool isActive = true;
bool isCompleted = false;
// Dart 中只有 true 被视为 true,其他所有值都是 false
if (isActive) {
print('激活状态');
}
4. 空值类型 (Null)
Dart 中只有 null,没有 undefined:
String? nullableString = null; // 可空类型
int? nullableInt = null;
集合类型
1. List - 列表
List 是有序的集合,类似于其他语言中的数组:
// 固定长度列表
List<int> fixedList = List.filled(3, 0); // [0, 0, 0]
// 可变长度列表
List<String> fruits = ['apple', 'banana', 'orange'];
List<dynamic> mixed = [1, 'hello', 3.14, true];
// 添加元素
fruits.add('grape');
fruits.addAll(['mango', 'pineapple']);
// 访问元素
print(fruits[0]); // apple
print(fruits.length); // 6
// 列表方法
fruits.remove('banana');
fruits.contains('apple'); // true
fruits.indexOf('orange'); // 2
2. Set - 集合
Set 是无序的、不重复的元素集合:
Set<String> uniqueNames = {'Alice', 'Bob', 'Charlie'};
Set<int> numbers = {1, 2, 3, 4, 5};
// 添加元素
uniqueNames.add('David');
uniqueNames.add('Alice'); // 不会添加,因为已存在
// Set 操作
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 是键值对的集合,类似于其他语言中的字典或对象:
// 字面量定义
Map<String, dynamic> person = {
'name': 'John',
'age': 30,
'city': 'Beijing'
};
// 构造函数定义
Map<String, int> scores = Map();
scores['math'] = 95;
scores['english'] = 88;
// 访问和修改
print(person['name']); // John
person['age'] = 31;
person['email'] = 'john@example.com'; // 添加新键值对
// Map 方法
person.containsKey('name'); // true
person.containsValue(30); // true
person.remove('city');
person.keys; // 获取所有键
person.values; // 获取所有值
特殊类型
1. Runes - 字符编码
Runes 用于表示 Unicode 字符:
String emoji = '😀';
Runes runes = emoji.runes;
print(runes); // (128512)
// 使用 Unicode 码点
String heart = '\u2665'; // ♥
String flag = '\u{1F1E8}\u{1F1F3}'; // 🇨🇳
2. Symbol - 符号
Symbol 用于表示 Dart 程序中的操作符或标识符:
Symbol symbol = #mySymbol;
print(symbol); // Symbol("mySymbol")
类型推断和声明
var - 类型推断
var 关键字让 Dart 自动推断变量类型:
var name = 'Flutter'; // 推断为 String
var count = 10; // 推断为 int
var price = 99.99; // 推断为 double
var isActive = true; // 推断为 bool
// 一旦推断,类型就固定了
// name = 123; // 错误!不能将 int 赋值给 String
dynamic - 动态类型
dynamic 表示变量可以是任何类型,类似于 JavaScript 的变量:
dynamic value = 'hello';
value = 123; // 可以重新赋值为不同类型
value = true;
value = [1, 2, 3];
Object - 对象基类
Object 是所有 Dart 对象的基类:
Object obj = 'string';
obj = 123;
obj = [1, 2, 3];
常量声明
const - 编译时常量
const 用于定义编译时常量,值必须在编译时确定:
const int maxCount = 100;
const String appName = 'MyApp';
const List<int> numbers = [1, 2, 3];
// const 对象的内容也不能修改
const Map<String, String> config = {
'apiUrl': 'https://api.example.com'
};
// config['apiUrl'] = 'new url'; // 错误!const 对象不可修改
final - 运行时常量
final 用于定义只能赋值一次的变量,值可以在运行时确定:
final int currentYear = DateTime.now().year; // 运行时确定
final String userName = getUserName(); // 运行时确定
// final 对象的内容可以修改(如果对象本身可变)
final List<int> list = [1, 2, 3];
list.add(4); // 可以修改列表内容
// list = [5, 6]; // 错误!不能重新赋值
final Map<String, String> map = {'key': 'value'};
map['key'] = 'new value'; // 可以修改 Map 内容
const vs final 的区别:
const:编译时常量,值必须在编译时确定final:运行时常量,值可以在运行时确定,但只能赋值一次
空安全 (Null Safety)
Dart 2.12 引入了空安全特性,提高了类型安全性:
可空类型和非空类型
// 非空类型(默认)
String name = 'Flutter';
// name = null; // 错误!不能为 null
// 可空类型(使用 ?)
String? nullableName;
nullableName = 'Flutter';
nullableName = null; // 可以
// 空值检查
if (nullableName != null) {
print(nullableName.length); // 安全访问
}
// 空值合并操作符
String result = nullableName ?? 'default'; // 如果为 null 则使用默认值
// 空值断言操作符(谨慎使用)
String forced = nullableName!; // 如果为 null 会抛出异常
空值感知操作符
String? name;
// ?. 安全调用
int? length = name?.length; // 如果 name 为 null,返回 null
// ??= 空值赋值
name ??= 'default'; // 只有当 name 为 null 时才赋值
// ?? 空值合并
String displayName = name ?? 'Unknown';
类型转换
数字类型转换
// String 转 int
int num1 = int.parse('123');
int? num2 = int.tryParse('abc'); // 返回 null,不会抛出异常
// String 转 double
double price1 = double.parse('99.99');
double? price2 = double.tryParse('invalid'); // 返回 null
// int/double 转 String
String str1 = 123.toString();
String str2 = 99.99.toStringAsFixed(1); // "100.0"
类型检查和转换
Object value = 'hello';
// 类型检查
if (value is String) {
print(value.length); // 自动转换为 String
}
// 类型转换
String str = value as String; // 强制转换,如果失败会抛出异常
泛型 (Generics)
Dart 支持泛型,提供类型安全:
// 泛型 List
List<int> numbers = [1, 2, 3];
List<String> names = ['Alice', 'Bob'];
// 泛型 Map
Map<String, int> scores = {'math': 95, 'english': 88};
// 泛型类
class Box<T> {
T value;
Box(this.value);
}
Box<int> intBox = Box(10);
Box<String> stringBox = Box('hello');
总结
Flutter/Dart 的数据类型系统特点:
- 强类型语言:所有变量都有明确的类型
- 类型推断:可以使用
var让编译器自动推断类型 - 空安全:通过
?和空值感知操作符提高安全性 - 丰富的集合类型:List、Set、Map 满足不同需求
- 常量支持:
const和final提供不同的常量语义 - 泛型支持:提供类型安全的集合和类
