跳转到正文
YGJoon 技术博客

Dart 变量和数据类型详解

发布于:
·1.3k 字 · 约 3 分钟·作者:
var、显式类型、dynamic 与 Object 如何取舍,final 和 const 有何区别,再过一遍数值、字符串、布尔类型的正确打开方式。
Dart 变量和数据类型详解文章封面
目录

变量声明

在 Dart 中,有多种方式声明变量:

var 关键字

var name = 'Bob'; // 类型推断为 String
var age = 20;     // 类型推断为 int

显式类型声明

String name = 'Bob';
int age = 20;
double height = 1.75;
bool isStudent = true;

dynamic 和 Object

dynamic value = 'Hello';
value = 123; // 可以改变类型

Object obj = 'Hello';
obj = 123;   // 也可以改变类型

final 和 const

final name = 'Bob';    // 运行时常量
const pi = 3.14159;    // 编译时常量

基本数据类型

数值型 (Numbers)

int

int age = 20;
int hexValue = 0xDEADBEEF;

double

double height = 1.75;
double exponents = 1.42e5;

字符串 (String)

字符串声明

String name = 'Bob';
String message = "Hello World";

字符串插值

String name = 'Bob';
String greeting = 'Hello, $name!';
String calculation = 'The sum is ${2 + 2}';

多行字符串

String multiLine = '''
This is a
multi-line string
in Dart.
''';

布尔型 (bool)

bool isStudent = true;
bool isWorking = false;

列表 (List)

List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['apple', 'banana', 'orange'];

集合 (Set)

Set<String> uniqueNames = {'Bob', 'Alice', 'Charlie'};
var numbers = {1, 2, 3, 4, 5};

映射 (Map)

Map<String, int> ages = {
  'Bob': 20,
  'Alice': 25,
  'Charlie': 30,
};

var scores = {
  'math': 90,
  'history': 85,
  'science': 95,
};

类型转换

字符串转换

// 字符串转数字
int.parse('123');      // 123
double.parse('1.23');  // 1.23

// 数字转字符串
123.toString();        // '123'
3.14159.toStringAsFixed(2);  // '3.14'

数值转换

// int 转 double
int age = 20;
double ageDouble = age.toDouble();

// double 转 int
double price = 9.99;
int priceInt = price.toInt();

空安全

Dart 2.12 引入了空安全特性:

// 可空类型
String? nullableName;  // 可以为 null
int? age;             // 可以为 null

// 非空类型
String nonNullName = 'Bob';  // 不能为 null
int nonNullAge = 20;        // 不能为 null

// 空值检查
String? name;
print(name?.length);  // 安全调用
print(name!.length);  // 强制非空

类型判断

is 关键字

var value = 'Hello';
if (value is String) {
  print('Value is a String');
}

runtimeType 属性

print(value.runtimeType);  // 打印运行时类型

常见用法示例

void main() {
  // 基本变量声明和使用
  String name = 'Bob';
  int age = 20;
  double height = 1.75;
  bool isStudent = true;
  
  // 字符串插值
  print('Name: $name, Age: $age, Height: $height, Student: $isStudent');
  
  // 列表操作
  var numbers = [1, 2, 3, 4, 5];
  numbers.add(6);
  numbers.remove(1);
  print('Numbers: $numbers');
  
  // Map操作
  var person = {
    'name': 'Bob',
    'age': 20,
    'height': 1.75,
  };
  person['weight'] = 65;
  print('Person: $person');
  
  // 空安全示例
  String? nullableName;
  print('Nullable name: ${nullableName ?? 'Unknown'}');
  
  // 类型转换
  var numberString = '123';
  var parsedNumber = int.parse(numberString);
  print('Parsed number: $parsedNumber');
}

注意事项

  1. 优先使用 var 声明变量,除非需要明确指定类型
  2. const 用于编译时常量,final 用于运行时常量
  3. 注意空安全特性,合理使用可空类型
  4. 避免滥用 dynamic 类型
  5. 使用类型推断时要注意上下文

最佳实践

  1. 变量命名使用小驼峰命名法
  2. 常量命名使用小驼峰命名法
  3. 优先使用字符串插值而不是字符串连接
  4. 合理使用 final 关键字提高代码的可维护性
  5. 显式声明API中的参数和返回类型

实战案例:给 JSON 的每个值”猜”一个 Dart 类型

ygking_json_to_dart_model 里有个 _getFieldType(dynamic value, String key) 方法,干的事就是”看一个 JSON 值,猜它该是什么 Dart 类型”。这是变量和数据类型最真实的应用场景:

// 逻辑示意(_getFieldType 的核心):
if (value is int) return 'int';
if (value is double) return 'double';
if (value is bool) return 'bool';
if (value is String) return 'String';
if (value is List) return 'List<...>';
if (value is Map) return key.capitalize();  // 嵌套对象→生成新类

然后生成的字段全部加 ?:int? age;、String? name;。为什么?因为 JSON 是外部输入,{"age": 25} 这次有 age,下次可能就没有。如果生成 int age;(非空),fromJson 里 json['age'] 一返回 null,直接抛异常。可空类型在这里不是”语法特性”,是”对不确定性的诚实”。

还有个 Dart 特有的坑:JSON 数字不分 int 和 double,25 和 25.0 在 JSON 里都是 number。Dart 的 json.decode 会把 25 解成 int、25.0 解成 double。我的 _getFieldType 必须分开判断——如果偷懒全按 num 生成,调用方每次用都要 as int,体验很差。类型的精度要跟数据源对齐,数据源分 int/double,你的类型就得跟着分。

dynamic vs var vs 明确类型,我的习惯是:能明确就明确(StringBuffer buffer = StringBuffer()),真不确定才 dynamic(final dynamic jsonData)。var 我反而少用——var 是”编译器帮我推”,dynamic 是”我明确表示不知道”。这两个心态完全不同,混用是很多隐性 bug 的来源。

总结

Dart 的变量和数据类型系统既灵活又严谨,通过合理使用可以写出更安全、更易维护的代码。类型是 Dart 里最便宜的文档——把类型写清楚,很多 bug 在运行前就被拦下了。


分享这篇文章:


相关文章

上一篇
Dart 元数据和注解详解
下一篇
Dart 函数和方法详解