变量是每一们语言的基础,在Dart中所有变量都是对象,并且都有一个初始化的值null。虽然在Dart中的变量的类型声明的是可选的,但是Dart建议在变量使用类型声明

变量声明与初始化

var name = 'Bob';

在dart中变量存储的是引用,在上面中代码中变量名name引用的是一个 String 对象值是"Bob"

这个name 变量会被Dart类型系统推断为 String ,如果你不确定的变量的类型,你也可以将变量指定为类型为 Object 或者 dynamic 类型。

dynamic name = 'Bob';
Object name = 'Bob'
String name = 'Bob';

Dart会基于上下文推断变量的类型。但在Dart的高效编程中则建议基于以下原则来确定类型声明

  • 如果代码是带类型注释的,则尽量声明类型
  • 如果代码是要经过推断的,不需要写类型声明,Dart会推断出变量本身的类型,如果推断失败,在某些地方会抛出一个静态错误,否则Dart会推断为 dynamic 类型
  • 如果代码是动态的,那么它的类型是 dynamic 类型。代码可以显式声明为dynamic ,或者使用var

但在某些操作中,Dart则建议使用 Object 代替 dynamic ,比如 log() 方法它需要调用任何对象的 toString() 方法,传递两种类型 Objectdynamic 在Dart中都是允许的,但是它们会传递不同的信息,如果你想简化传递的信息则使用 Object 类型,就像java和C#一样

使用dynamic 则传递更为复杂的信号,这意味着Dart类型系统表达不了该类型的值,或者这些值是来自代码互相操作结果又或者你在程序中明确要求是运行时是动态的。

void log(Object object) {
  print(object.toString());
}

/// Returns a Boolean representation for [arg], which must
/// be a String or bool.
bool convertToBool(dynamic arg) {
  if (arg is bool) return arg;
  if (arg is String) return arg == 'true';
  throw ArgumentError('Cannot convert $arg to a bool.');
}

变量默认值

未初始化的变量都有一个初始化的值 null ,包括数值类型变量都是 null ,因为在Dart中一切都是对象

int lineCount;
assert(lineCount == null);

Final and const

如果你一直不打算改变变量,则可以将变量声明为 final 或者 const ,final变量只有可以赋值一次,常量变量是编译时的常量(即隐式的final),final在类中使用之前必须被初始化

final name = 'Bob'; // 没有类型声明
final String nickname = 'Bobby';

const关键字不仅用于声明常量变量。您还可以使用它来创建常量值,以及声明创建常量值的构造函数。任何变量都可以具有常量值。

var foo = const [];
final bar = const [];
const baz = []; // 相当于 const []

您可以更改非final,非const变量的值,即使它曾经有一个常量值

foo = [1, 2, 3]; // foo在上面被赋值为一个常量值const []

您无法更改const变量的值

baz = [42]; // Error: Constant variables can't be assigned a value.