Skip to content

变量与类型

Dart 中的变量

变量是存储数据值的容器。Dart 是一种静态类型语言,具有类型推断功能,这意味着你可以使用或不使用显式类型来声明变量。

变量声明

使用 var

var 关键字让 Dart 推断类型:

dart
var name = 'Alice';        // String
var age = 25;              // int
var height = 5.8;          // double
var isStudent = true;      // bool

一旦赋值,类型就固定了:

dart
var count = 10;
// count = 'ten';  // 错误:类型 'String' 的值不能赋给类型 'int' 的变量

显式类型声明

你可以显式指定类型:

dart
String name = 'Bob';
int age = 30;
double price = 19.99;
bool isActive = false;

动态类型

当类型可以改变时使用 dynamic

dart
dynamic value = 42;
value = '现在是字符串';  // 可以
value = true;            // 可以

⚠️ 警告:尽可能避免使用 dynamic,因为它绕过了类型安全。

Final 和 Const

final

final 变量只能设置一次:

dart
final String city = '纽约';
// city = '波士顿';  // 错误:不能赋值给 final 变量

final currentTime = DateTime.now();  // 运行时设置

const

const 变量是编译时常量:

dart
const double pi = 3.14159;
const int maxUsers = 100;

// const now = DateTime.now();  // 错误:必须是编译时常量

finalconst 的区别

dart
final list1 = [1, 2, 3];
const list2 = [1, 2, 3];

list1.add(4);  // 可以:列表本身可以修改
// list2.add(4);  // 错误:不能修改 const 列表

// final 在运行时设置
final time1 = DateTime.now();

// const 必须在编译时已知
const time2 = DateTime.now();  // 错误!

内置类型

1. 数字

int

整数值(64 位,-2^63 到 2^63-1):

dart
int score = 95;
int hexValue = 0xFF;
int negativeNum = -42;

double

64 位浮点数:

dart
double temperature = 36.6;
double price = 99.99;
double scientific = 1.42e5;  // 142000.0

num

intdouble 的父类型:

dart
num value1 = 10;      // int
num value2 = 10.5;    // double

2. 字符串

字符串表示字符序列:

dart
String greeting = '你好';
String message = "欢迎";
String multiline = '''
这是一个
多行
字符串
''';

3. 布尔值

布尔值是 truefalse

dart
bool isLoggedIn = true;
bool hasPermission = false;

4. 列表(数组)

对象的有序集合:

dart
List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['苹果', '香蕉', '橙子'];

// 访问元素
print(fruits[0]);  // 苹果

// 修改
fruits.add('葡萄');
fruits[1] = '芒果';

5. 集合

唯一项的无序集合:

dart
Set<String> colors = {'红色', '绿色', '蓝色'};
var numbers = {1, 2, 3, 3, 4};  // {1, 2, 3, 4} - 重复项被移除

colors.add('黄色');
colors.remove('红色');

6. 映射

键值对:

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

// 访问值
print(ages['Alice']);  // 25

// 添加/修改
ages['David'] = 28;
ages['Alice'] = 26;

7. Runes

字符串的 Unicode 码点:

dart
var heart = '\u2665';  // ♥
var smiley = '\u{1F600}';  // 😀

Runes input = Runes('\u2665 \u{1F600}');
print(String.fromCharCodes(input));  // ♥ 😀

8. Symbols

反射中使用的标识符:

dart
Symbol sym = #mySymbol;

类型检查和转换

使用 is 进行类型检查

dart
var value = 42;

if (value is int) {
  print('这是一个整数');
}

if (value is! String) {
  print('这不是字符串');
}

使用 as 进行类型转换

dart
dynamic obj = '你好';
String str = obj as String;  // 转换为 String

// 安全转换
if (obj is String) {
  String str = obj;  // 不需要转换,类型提升
}

默认值

未初始化的变量默认值为 null

dart
int? count;
print(count);  // null

String? name;
print(name);  // null

Late 变量

对于稍后初始化的变量使用 late

dart
late String description;

void initialize() {
  description = '稍后初始化';
}

void main() {
  initialize();
  print(description);  // 可以
}

类型推断

Dart 可以从上下文推断类型:

dart
var numbers = [1, 2, 3];  // List<int>
var map = {'key': 'value'};  // Map<String, String>

// 泛型类型推断
var list = <String>[];  // List<String>

最佳实践

  1. 优先使用 var 或显式类型而不是 dynamic
  2. 对不会改变的变量使用 final
  3. 对编译时常量使用 const
  4. 在公共 API 中明确类型
  5. 当类型明显时,对局部变量使用类型推断

示例

完整示例

dart
void main() {
  // 基本类型
  var name = 'Alice';
  int age = 25;
  double height = 5.8;
  bool isStudent = true;
  
  // 集合
  List<String> hobbies = ['阅读', '编程', '游戏'];
  Map<String, dynamic> person = {
    'name': name,
    'age': age,
    'hobbies': hobbies,
  };
  
  // 常量
  const double pi = 3.14159;
  final currentDate = DateTime.now();
  
  // 打印信息
  print('姓名:$name');
  print('年龄:$age');
  print('身高:$height 米');
  print('是学生:$isStudent');
  print('爱好:${hobbies.join('、')}');
  print('个人信息:$person');
  print('圆周率:$pi');
  print('日期:$currentDate');
}

下一步

现在你已经了解了变量和类型,让我们探索: