Dart 学习笔记-1- variables

98 阅读4分钟

基础概念

变量可以显示声明类型,比如:

String name = 'Bob';

也可以隐式声明,如:

var name = 'Bob';

以上语句中,变量name的类型被推断为String。

name变量包含一个值为”BOb“的String对象的引用。

如果一个对象不受限于单一类型,可以指定为Object类型,如下:

Object name = 'Bob';

空安全

空安全可以防止意外访问null得变量而导致的错误,也叫空解引用错误。例如在js中,执行如下代码:

const index = arr.indexOf('1');

当变量arr为null或者undefined时,就会产生:Uncaught TypeError: Cannot read properties of null (reading 'indexOf')这种运行时错误。 但是dart编译器禁止这些操作,所以dart应用程序不会引发运行时错误。

空安全引入了三个关键更改:

  1. 当你为变量、参数或者另一个相关组件指定类型时,可以控制该类型是否允许为null。要让一个变量可以为空,可以在类型声明的末尾添加:?, 如:

    String? name // name赋值时可以是一个字符串,也可以是null
    String name // name赋值时,只能是字符串
    
  2. 你必须在使用变量之前对其进行初始化。可空变量默认初始化为null;但是dart不会给非可空类型设置初始值,它强制要求开发者进行设置。如果没有这个变量没有设置初始值,则不可以被观察(比如在print方法中打印,或者调用操作它的一些方法)。This prevents you from accessing properties or calling methods where the receiver’s type can be null but null doesn’t support the method or property used。(这句话好绕,我的理解:这个更改可以防止在使用一些可以是null的变量,被使用或者调用一些null不支持的方法或者属性。)

  3. 你不能在可空类型的表达式上访问属性或调用方法。 null 支持的属性或方法,例如 hashCode 或 toString() 例外 。

空安全将潜在的运行时错误转变为了编辑时分析错误,可以提升我们的代码质量。

默认值

可空类型未初始化变量的初始值为null。非空变量声明时可以不需要初始化,但是在使用之前需要为其赋值。

顶级变量和类变量会被延迟初始化,它们会在第一次被使用时再初始化。

延迟初始化变量

late修饰符,用法:

  • 声明一个非空变量,但不在声明时初始化
  • 延迟初始化一个变量

dart的语义分析可以检测非空变量在使用之前是否被赋值,但是有时会分析失败。常见情况是分析顶级变量和实例变量时。dart通常无法确定它们是都已经设值,因此不会尝试分析。

如果确定变量在使用之前已经设值,但是dart推断错误的话。可以将变量标记为late来解决这个问题。

初始化延迟的适用情况:

  • Dart推断 可能不需要该变量,并且初始化它的开销很高
  • 初始化一个实例变量,初始化方法需要调用this
late String temperature = readThermometer(); // 如果temperature没有被使用,则readThermometer这个开销较大的函数也永远不会被调用;

终值finnal和常量const

一个 final 变量只能设置一次,const 变量是编译时常量。(const 常量隐式包含了 final。)

final name = 'Bob';
name = 'Alice'; //  Error: a final variable can only be set once.

const bar = 1000;
const baz = []; // Equivalent to const baz = const []

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

var foo = const []; // foo 虽然有一个 const修饰的 [] 常量值,但是它本身不是一个const 或者final变量,因此变量foo可以被修改
foo = [1,2,3]; // 可以被修改
final bar = const []; // 不可以被修改

虽然 final 对象不能被修改,但它的字段可能可以被更改。相比之下,const 对象及其字段不能被更改:它们是不可变的。