# 变量

## 使用`var`定义变量

类似于JavaScript中的`var`，使用它可以定义任意类型的变量。

> ⚠️注意：在Dart中，使用`var`定义的变量一旦被赋值，那么其数据类型便会确定，不能再修改其类型。

```dart
var t = 'hello world';
t = 1000; // ERROR: A value of type 'int' can't be assigned to a variable of type 'String'
```

## 使用`dynamic`和`Object`定义变量

在Dart中，`Object`是所有对象的根基类（即所有类型都是`Object`的子类，包括`Function`和`Null`），所以任何类型的数据都可以赋值给`Object`声明的对象。

```dart
dynamic t;
t = 'hello world';
t = 1000; // NO ERROR
```

`dynamic`与`Object`不同的是`dynamic`声明的对象编译器会提供所有可能的组合，而`Object`声明的对象只能使用`Object`的属性与方法，否则编译器会报错。

```dart
dynamic a;
Object b = '';
main() {
  a = '';
  printLengths();
}
printLengths() {
  print(a.length); // NO ERROR
  print(b.length); // ERROR: The getter 'length' isn't defined for the type 'Object'
}
```

## 空安全

JavaScript中最常见的错误就是“空指针错误”，在尝试访问`null`或`undefined`值的属性或方法时发生。

```js
var obj = null;
console.log(obj.property); // ERROR: Cannot read property 'property' of null
```

Dart在2.12版本中引入了空安全的概念，空安全是指在处理变量和对象时，确保它们的值不为`null`，从而减少代码中的空指针异常和其他相关错误。 如果一个变量可以为空，需要在类型声明的末尾添加`?`，不能在可空类型的表达式上访问属性或调用方法。Dart不会为非可空类型设置初始值，因此在使用之前需要设置初始值。

```dart
String? name  // Nullable type. Can be `null` or string
String name   // Non-nullable type. Cannot be `null` but can be string
print(name.length);  // ERROR: The property 'length' can't be unconditionally accessed because the receiver can be 'null'
print(name2.length); // ERROR: The non-nullable local variable 'name2' must be assigned before it can be used
```

Dart也提供了一些操作符来处理可空类型，避免因空值导致的异常：

* 安全调用操作符`?.`：用于在对象可能为空时安全地调用其方法或访问其属性。
* 非空断言操作符`!.`：用于在确定一个可空变量不为空时，将其转换为非空类型（如果断言错误，会抛出运行时异常）。
* 空合并操作符`??`：用于在变量为空时提供默认值。

```dart
String? name = 'Dart';
print(name!.length);
print(name ?? 'Default Name');
```

## 终值和常量

与变量不同，常量的值在程序执行期间不会改变，可以使用`final`或`const`关键字来声明常量。

> ⚠️注意：`final`声明的常量在运行时初始化，而`const`声明的是编译时常量。

```dart
final name = 'Bob';
final String nickname = 'Bobby';
const bar = 1000000;
const double atm = 1.01325 * bar;
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dart-2.gitbook.io/dart-ru-men-jiao-cheng/2-basis/2-1-variable.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
