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 教程。