Dart 中的类型转换
最后修改于 2025 年 5 月 25 日
Dart 是一种静态类型语言,拥有健全的类型系统,其类型转换方式与动态类型语言不同。本教程涵盖了 Dart 的类型转换系统,包括显式类型转换、解析和转换方法。
Dart 类型转换概述
Dart 的类型转换系统旨在实现显式和类型安全。它允许您在兼容类型之间进行转换,同时防止可能导致运行时错误的隐式转换。主要的转换技术包括显式类型转换、数字解析、字符串转换和类型提升。
转换类型 | 描述 | 示例 |
---|---|---|
显式类型转换 | 使用 as 操作符进行类型断言 |
var str = obj as String; |
数字解析 | 将字符串转换为数字 | int.parse('42') |
字符串转换 | 转换为字符串表示形式 | 123.toString |
类型提升 | 在控制流中自动进行 | if (obj is String) {...} |
关于 Dart 类型转换的关键点
- 使用
as
进行显式类型断言 - 如果类型不兼容,将抛出
TypeError
- 如果不确定,请始终使用
is
检查类型后再进行转换 - 不相关类型之间没有隐式转换
显式类型转换
Dart 使用 as
操作符在兼容类型之间进行显式类型转换。
void main() { dynamic value = 'Hello Dart'; // Safe casting with 'as' String str = value as String; print('String length: ${str.length}'); // This would throw TypeError at runtime: // int number = value as int; // Safe casting with type check if (value is String) { print('Uppercase: ${value.toUpperCase()}'); } }
在 Dart 中,类型转换是显式的,需要 as
操作符。这允许您断言一个值是特定类型。如果该值与目标类型不兼容,运行时将抛出 TypeError
。
$ dart run casting.dart String length: 10 Uppercase: HELLO DART
数字解析和转换
Dart 提供了多种将字符串转换为数字以及在数字类型之间进行转换的方法。
void main() { // String to number int intVal = int.parse('42'); double doubleVal = double.parse('3.14'); // Number to string String intStr = 42.toString(); String doubleStr = 3.14159.toStringAsFixed(2); // Between numeric types double d = 5; // int to double int i = 3.14.toInt(); // double to int (truncates) print('Parsed int: $intVal'); print('Parsed double: $doubleVal'); print('Int to string: $intStr'); print('Formatted double: $doubleStr'); print('Double to int: $i'); // Safe parsing with tryParse int? maybeInt = int.tryParse('abc'); print('TryParse result: $maybeInt'); }
int.parse
和 double.parse
方法将字符串转换为各自的数字类型。如果字符串无法解析,将抛出 FormatException
。为了避免这种情况,您可以使用 tryParse
,如果解析失败,它将返回 null
。
toString
方法将数字转换为其字符串表示形式。您还可以使用 toStringAsFixed
来格式化小数位数,以及使用 toInt
或 toDouble
在数字类型之间进行转换。Dart 不允许数字类型之间的隐式转换,因此您必须显式使用这些方法。
$ dart run number_conversion.dart Parsed int: 42 Parsed double: 3.14 Int to string: 42 Formatted double: 3.14 Double to int: 3 TryParse result: null
字符串转换
在 Dart 中,使用几种可用选项将值转换为字符串非常简单。
void main() { // Basic toString() String intStr = 42.toString(); String boolStr = true.toString(); // String interpolation automatically calls toString() String interpolated = 'Value: ${123}, Bool: ${false}'; // More complex formatting String pi = 3.14159.toStringAsFixed(2); String hex = 255.toRadixString(16); print('intStr: $intStr'); print('boolStr: $boolStr'); print('interpolated: $interpolated'); print('pi: $pi'); print('hex: $hex'); }
toString
方法在 Dart 中的所有对象上都可用,允许您将任何值转换为其字符串表示形式。Dart 还支持字符串插值,当在字符串中使用对象时,它会自动调用对象的 toString
方法。这使得从各种类型创建格式化字符串变得容易。
$ dart run string_conversion.dart intStr: 42 boolStr: true interpolated: Value: 123, Bool: false pi: 3.14 hex: ff
Dart 中的类型提升
Dart 在某些控制流情况下会自动提升类型,在不进行显式类型转换的情况下提供类型安全。
void main() { dynamic value = 'Dart'; // Type promotion in conditionals if (value is String) { print('Length: ${value.length}'); // value is now String } // Promotion with null checks String? maybeString; if (maybeString != null) { print('Length: ${maybeString.length}'); // maybeString is non-null } // Promotion with logical operators Object obj = 'Hello'; if (obj is String && obj.length > 3) { print('Long string: $obj'); } }
Dart 的类型提升在 is
类型检查、Null 检查(!= null
, == null
)、逻辑表达式(&&
, ||
)和异常捕获之后起作用。
$ dart run type_promotion.dart Length: 4 Long string: Hello
使用集合
Dart 提供了在不同集合类型之间进行转换的方法。
import 'dart:collection'; void main() { // List conversions List<int> numbers = [1, 2, 3]; List<String> strings = numbers.map((n) => n.toString()).toList(); // Set from List Set<int> uniqueNumbers = numbers.toSet(); // Map from List Map<int, String> map = {for (var n in numbers) n: 'Number $n'}; // Convert to different collection types var fixedList = List<int>.unmodifiable(numbers); var linkedHashSet = LinkedHashSet<int>.from(numbers); print('Strings: $strings'); print('Unique numbers: $uniqueNumbers'); print('Map: $map'); print('Fixed List: $fixedList'); print('LinkedHashSet: $linkedHashSet'); }
toList
、toSet
和 map
方法提供了在 Dart 中集合之间进行转换的便捷方式。您还可以使用 List.from
和 Set.from
等构造函数创建新集合。
$ dart run collection_conversion.dart Strings: [1, 2, 3] Unique numbers: {1, 2, 3} Map: {1: Number 1, 2: Number 2, 3: Number 3} Fixed List: [1, 2, 3] LinkedHashSet: {1, 2, 3}
JSON 序列化
Dart 为与 JSON 的相互转换提供了内置支持。
import 'dart:convert'; // Custom objects need toJson/fromJson methods class Language { final String name; final double version; Language(this.name, this.version); Map<String, dynamic> toJson() => {'name': name, 'version': version}; factory Language.fromJson(Map<String, dynamic> json) { return Language(json['name'], json['version']); } } void main() { // Convert to JSON Map<String, dynamic> data = {'name': 'Dart', 'version': 2.19, 'isCool': true}; String jsonStr = jsonEncode(data); // Parse from JSON Map<String, dynamic> decoded = jsonDecode(jsonStr); print('Original: $data'); print('JSON: $jsonStr'); print('Decoded: $decoded'); Language dart = Language('Dart', 2.19); String langJson = jsonEncode(dart); Language decodedLang = Language.fromJson(jsonDecode(langJson)); print('Language JSON: $langJson'); print('Decoded language: ${decodedLang.name} ${decodedLang.version}'); }
dart:convert
库提供了 JSON 序列化和反序列化的方法。它允许您轻松地将 Dart 对象转换为 JSON 字符串,并将 JSON 字符串解析回 Dart 对象。
您可以使用 jsonEncode
和 jsonDecode
方法处理基本类型、列表和映射。对于自定义类,您需要实现 toJson
和 fromJson
方法来处理序列化和反序列化。它可以开箱即用地处理原始类型、列表和映射。
$ dart run json_conversion.dart Original: {name: Dart, version: 2.19, isCool: true} JSON: {"name":"Dart","version":2.19,"isCool":true} Decoded: {name: Dart, version: 2.19, isCool: true} Language JSON: {"name":"Dart","version":2.19} Decoded language: Dart 2.19
来源
Dart 的类型转换系统通过静态类型提供了安全性,并通过显式转换方法提供了灵活性。理解这些转换技术对于编写健壮的 Dart 应用程序至关重要。
作者
列出 所有 Dart 教程。