⚠️ 阅读前提示:本文包含大量隐藏技巧和容易被忽视的细节!建议配合官方文档食用
目录
- 基础类型
- 1.1 数字类型
- 1.2 字符串类型
- 1.3 布尔类型
- 动态类型
- 集合类型
- 空安全与类型推断陷阱
- 类型检查与转换
1. 基础类型
1.1 数字类型
int:不仅是整数,还支持不同进制表示
dartint hex = 0xDEADBEEF; // 十六进制 int binary = 0b1101101; // 二进制(新手容易写错前导0b)double:浮点数陷阱
dartdouble a = 1; // ✅ 自动转换为1.0 int b = 2.0; // ❌ 编译报错!(新手常见错误)
⛔ 易忽略点:
- int 和 double 都是
num的子类型,但自动转换只有 double → num 允许 - 使用
整数.toDouble()显式转换更安全
| 方法 | 描述 | 示例 |
|---|---|---|
| floor() | 向下取整 | 3.9.floor() → 3 |
| ceil() | 向上取整 | 3.1.ceil() → 4 |
| round() | 四舍五入 | 3.5.round() → 4 |
1.2 字符串类型
单引号 vs 双引号:Dart中两者等价,但要注意嵌套使用
dartString s1 = 'It\'s a book'; // 正确转义 String s2 = "It's easier"; // 更优方案三引号的妙用(新手极少用但实用):
dartString poem = ''' 床前明月光, 疑是地上霜。 '''; // 自动保留换行和缩进格式
💡 字符串插值隐藏规则:
- 只有表达式才能用
${...},语句不可用dart'结果是${a + b}' // ✅ '数值是${if(a>0) a else b}' // ❌(控制流语句不能放在插值中)
1.3 布尔类型
Dart 的严格规则(与JavaScript不同):
- 只有
true和false才视为布尔值 - 其他类型(如0、空字符串、空集合)不会隐式转换
🚨 错误案例:
dart
if ('') { /* 不会执行 */ } // **错误!** 编译不通过
var visible = 'true'; // 类型是String!
if (visible) { ... } // 类型不匹配错误2. 动态类型
dynamic vs var(新手易混淆概念):
dart
dynamic a = 'Hello';
a = 10; // ✅ 允许修改类型
var b = 'World';
b = 100; // ❌ 类型已被推断为String⚠️ 使用建议:
- 避免滥用
dynamic,会失去类型安全检查优势 - 在需要后期确定类型时,优先使用
Object?
3. 集合类型
3.1 List底层机制
创建List的三种方式与区别:
dart
var list1 = [1, 2, 3]; // 推断为List<int>
List<dynamic> list2 = [1, 'a']; // 动态类型列表
var list3 = List.filled(5, ''); // 定长列表(新手常忘记长度不可变)💥 展开操作符的陷阱:
dart
var list = [1, 2];
var newList = [...?list]; // 空安全操作符(当list为null时自动处理)3.2 Map关键特性
键值类型一致性规则:
dart
Map<String, int> age = {
'Alice': 20,
20: 30 // ❌ 类型不匹配!(错误很隐蔽)
};💡 遍历技巧(新手常遗漏):
dart
map.forEach((k,v) => print('$k : $v'));3.3 Set的独特性质
- 自动去重机制基于哈希码
- 可以用于快速判断包含关系
dart
var set = {1, 2, 3};
print(set.contains(2)); // true(比List判断效率高)4. 空安全与类型推断陷阱
不可忽视的代码规范:
dart
int a; // ❌ 非空变量必须初始化
int? b; // ✅ 可空变量允许后期赋值
late int c; // 延迟初始化(新手易误用作可空替代)🔥 类型推断的特殊情况:
dart
var list = [];
list.add(1); // 实际类型为List<dynamic>!
list.add('a'); // 允许但危险(应指定泛型)5. 类型检查与转换
安全转换秘诀
dart
// 危险方式
String s = 123 as String; // 可能抛出异常
// 安全方式
if (123 is String) { // 先检查类型
// 不会执行到这里
}
// 安全转换方法
num n = 3.14;
double d = n.toDouble(); // 最佳实践🌟 推荐工具方法:
dart
dynamic value = GetUserInput();
// 泛型类型检查扩展方法(避免重复代码)
T safeCast<T>(dynamic value, [T? defaultValue]) {
return value is T ? value : defaultValue ?? T();
}✅ 总结要点:
- Dart是强类型语言,但有灵活的推断机制
- 空安全是编译时的强力保障,不是运行时检查
- 集合类型的泛型参数至关重要
- 合理使用类型转换避免运行时错误
延伸思考问题:
- 为什么
const Object arr = [1,2,3]会被Dart拒绝? - 当混合使用
num和int时可能遇到哪些隐蔽问题? - 如何通过泛型实现类型安全的空列表创建?