header-bg.jpg
Dart 基本概念之变量
发表于 2019-07-03 12:47
|
分类于 Dart
|
评论次数 0
|
阅读次数 354

任何语言的核心都必然会描述这门语言最基本的工作原理。而描述的内容通常都要设计这门语言的语法、操作符、数据类型、内置功能等用于构建复杂解决方案的基本概念。

我分了几篇文章将对 Dart 的基本概念进行全面的总结:

下面开始正文。

在 Dart 中声明一个变量可以用 varfinalconst 来声明,在 Dart 中文手册 中的相关描述很模糊,所以我整理之后在本文记录一下这 3 个关键字的区别。

var

用法示例:

main() {
  var name = 'Bob';
  name = 'leo';
  print(name);
}
// output: leo

上面的代码中,名为 name 的变量引用了 一个内容为 BobString 对象,接着更改 name 的值为 leo,最后输出 leo

很明显,var 的用法在 JavaScript 里是一样的,但是有一点是需要注意的,Dart 中的 var 在声明后立即赋值,之后就无法修改数据类型,例如下面的代码将会报错:

main() {
  var foo = 'test';
  foo = 123;
}
// Error: A value of type 'int' can't be assigned to a variable of type 'String'.
// Try changing the type of the left hand side, or casting the right hand side to 'String'.
//  foo = 123;
//        ^

如果只是单纯地声明一个变量,不进行赋值,则这个变量是 dynamic 类型的变量,可以任意修改数据类型:

main() {
  var foo;
  foo = 'test';
  foo = 123;
}

下面这种使用 dynamic 关键字的写法和上面使用 var 关键字的写法是等价的:

main() {
  dynamic foo = 'test';
  foo = 123;
}

finalconst

使用 final 或者 const 声明的变量只能赋值一次,赋值之后就不能再更改了,这和 JavaScript 中 const 的用法也是一摸一样,例如以下代码将会报错:

main() {
  const a = 'Bob';
  a = 'Leo';
}

// Error: Setter not found: 'a'.
//  a = 'Leo';
//  ^
// Error: Compilation failed.

finalconst 有什么区别呢?官网是这样介绍的:

一个 final 变量只能赋值一次;一个 const 变量是编译时常量。 (Const 变量同时也是 final 变量。) 顶级的 final 变量或者类中的 final 变量在 第一次使用的时候初始化。

?.gif

👴真的人晕了。。。

以我的理解就是:constfinal 更加严格,具体有如下几种表现:

const 声明的变量,值必须是确定的

例如用 const 声明变量 foo,赋值为 DateTime.now(),将会报错:

main() {
  const foo = DateTime.now();
}

// Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// const foo = DateTime.now();
//                       ^^^
// Error: Compilation failed.

而用 final 声明变量 foo,赋值为 DateTime.now(),则会正常输出当前时间:

main() {
  final foo = DateTime.now();
  print(foo);
}

// output: 2019-07-03 12:21:31.350

const 声明的变量,值如果包含变量,那这些被包含的变量也必须使用 const 声明

例如声明变量 sum,值为 foobar 之积,将正常输出 6

main() {
  const foo = 2;
  const bar = 3;
  const sum = foo * bar;
  print(sum);
}

// output: 6

如果你使用 final 声明上面代码中的 foobar,将会报错:

main() {
  final foo = 2;
  const bar = 3;
  const sum = foo * bar;
  print(sum);
}

// Error: Not a constant expression.
// const sum = foo * bar;
//             ^^^
// Error: Compilation failed.

如果使用 final 或者 var 声明变量 sum,就能正常运行:

main() {
  final foo = 2;
  const bar = 3;
  final sum = foo * bar;
  print(sum);
}

// output: 6

final 声明 listsmaps 类型的变量,可以更改其属性,而 const 不能

Dart 中的 finalJavaScript 中的 const 特性非常相似,例如如下代码将正常运行:

main() {
  final foo = [1, 2, 3];
  foo[1] = 666;
  print(foo);
}

// output: [1, 666, 3]
main() {
  final foo = {'name': 'Bob'};
  foo['name'] = 'Leo';
  print(foo);
}

// output: {name: Leo}

const 就非常严格,如果你将上面代码中的 final 替换为 const,将会报错:

main() {
  const foo = [1, 2, 3];
  foo[1] = 666;
  print(foo);
}

// Uncaught exception:
// Unsupported operation: indexed set
main() {
  const foo = [1, 2, 3];
  foo[1] = 666;
  print(foo);
}

// Uncaught exception:
// Unsupported operation: Cannot modify unmodifiable Map

变量的值相同时,final 将在内存中重复创建,而 const 将引用相同值

例如如下代码声明 foobar 的值都为 [1, 2, 3],比较 foobar,输出 false

main() {  
  final foo = [1, 2, 3];
  final bar = [1, 2, 3];
  print(foo == bar);
}

// output: false

如果将上面代码中的 final 替换为 const,则会输出 true, 因为 const 引用的是同一份地址:

main() {  
  const foo = [1, 2, 3];
  const bar = [1, 2, 3];
  print(foo == bar);
}

// output: true

发布评论
还没有评论,快来抢沙发吧!