ZetCode

Dart 中的类型转换

最后修改于 2025 年 5 月 25 日

Dart 是一种静态类型语言,拥有健全的类型系统,其类型转换方式与动态类型语言不同。本教程涵盖了 Dart 的类型转换系统,包括显式类型转换、解析和转换方法。

Dart 类型转换概述

Dart 的类型转换系统旨在实现显式和类型安全。它允许您在兼容类型之间进行转换,同时防止可能导致运行时错误的隐式转换。主要的转换技术包括显式类型转换、数字解析、字符串转换和类型提升。

转换类型 描述 示例
显式类型转换 使用 as 操作符进行类型断言 var str = obj as String;
数字解析 将字符串转换为数字 int.parse('42')
字符串转换 转换为字符串表示形式 123.toString
类型提升 在控制流中自动进行 if (obj is String) {...}

关于 Dart 类型转换的关键点

显式类型转换

Dart 使用 as 操作符在兼容类型之间进行显式类型转换。

casting.dart
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 提供了多种将字符串转换为数字以及在数字类型之间进行转换的方法。

number_conversion.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.parsedouble.parse 方法将字符串转换为各自的数字类型。如果字符串无法解析,将抛出 FormatException。为了避免这种情况,您可以使用 tryParse,如果解析失败,它将返回 null

toString 方法将数字转换为其字符串表示形式。您还可以使用 toStringAsFixed 来格式化小数位数,以及使用 toInttoDouble 在数字类型之间进行转换。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 中,使用几种可用选项将值转换为字符串非常简单。

string_conversion.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 在某些控制流情况下会自动提升类型,在不进行显式类型转换的情况下提供类型安全。

type_promotion.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 提供了在不同集合类型之间进行转换的方法。

collection_conversion.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');
}

toListtoSetmap 方法提供了在 Dart 中集合之间进行转换的便捷方式。您还可以使用 List.fromSet.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 的相互转换提供了内置支持。

json_conversion.dart
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 对象。

您可以使用 jsonEncodejsonDecode 方法处理基本类型、列表和映射。对于自定义类,您需要实现 toJsonfromJson 方法来处理序列化和反序列化。它可以开箱即用地处理原始类型、列表和映射。

$ 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 的类型转换系统通过静态类型提供了安全性,并通过显式转换方法提供了灵活性。理解这些转换技术对于编写健壮的 Dart 应用程序至关重要。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 Dart 教程