Dart 的注释与变量

393 阅读4分钟

我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123… 。

今天继续学习 Flutter 的编程语言 Dart 的语法基础,主要是关于注释和变量这两方面的内容。

注释

注释分成 3 种:

  1. 单行注释

使用 //,同 js 是一样的:

// 我是单行注释
  1. 多行注释

多行注释以 /* 开始,以 */ 结尾,也与 js 一样:

/* 
  我是多行
  注释
 */
  1. 文档注释

dart 中还有种 js 没有的注释,叫做文档注释,以 /// 开头:

/// 我收文档注释

将来可以通过 dartdoc 将注释生成文档,并且文档注释还支持 Markdown 语法。

变量

在 dart 中,万物皆为对象,变量只是存储着对象的引用。

声明变量

dart 中声明变量,从大的方面看可以分成 2 种:

1. 明确指定类型

比如我想声明一个字符串类型的变量 name,就可以直接写个类型,后面跟变量名:

void main() {
  String name = 'Jay';
  print(name.runtimeType); // String
}

在 dart 中,所有变量都有个 runtimeType 属性,可以查看变量的类型。
注:main 函数为入口函数,想要运行 dart 代码是必需的,更多细节可移步《Flutter 基础之 Dart 初识》

2. 类型推断

我们可以使用关键字 var/final/const 来不明确指定类型地声明变量(还有个 dynamic 关键字以后再说)。

var

请注意,没有明确指定类型不代表没有类型。比如我们用 var 声明了变量 name,值为字符串 Jay,之后如果修改 name 的值为其它 String 类型的值,如 Zhou,是可以的。但是将 name 赋值为 int 类型的值 20,就会报错:

void main() {
  var name = 'Jay';
  name = 'Zhou'; // 可以修改
  name = 20; // A value of type 'int' can't be assigned to a variable of type 'String'.
}

var 不能和类型一起使用,比如 var int count; 是会报错的。

final

这个在 js 中没有的关键字 final,在 dart 中用于声明常量,一旦赋值之后就不能修改了:

void main() {
  final name = 'Jay';
  name = 'Zhou'; // The final variable 'name' can only be set once.
}

final 可以和类型一起使用,比如 final String msg;

const

const 在 dart 中同在 js 中一样是用于声明常量。

void main() {
  const name = 'Jay';
  name = 'Zhou'; // Constant variables can't be assigned a value.
}
final 与 const 的区别

既然 finalconst 都是用来声明常量的,那它们之间有什么区别呢?

const 声明的变量必须赋值,这点同 js 一致。另外,该值还得是个常量值,是个编译期间就确定的值,不能是运行时确定的值:

void main() {
  const time = DateTime.now(); // 报错
}

上例中, DateTime 是 dart 中的一个类,可以通过调用它的 now() 方法来动态获取当前的时间。显然这个时间是需要在代码运行时获取的,所以如果直接赋值给 const 声明的 time,就会报错。 而赋给 final 声明的变量的值可以是通过计算或是函数返回等运行期间确定的值:

void main() {
  final time = DateTime.now();
  print(time); // 2022-06-05 16:23:30.436420
}

编写 flutter 项目时,在定义一些 Widget 时经常会用到 const,比如定义边距 padding: const EdgeInsets.all(10),使用 const 的目的在于当传入的值一样时,只会创建一个对象,从而减少内存的占用。下面举个例子说明:

void main() {
  final p1 = Person('Jay');
  final p2 = Person('Jay');
  print(identical(p1, p2)); // false
}

class Person {
  String name;
  Person(this.name);
}

使用 final 声明的 p1p2,都通过 Person('Jay')(前面省略了 new)得到,传入的参数是一样的,但是 p1p2 却并不是同一个对象,identical 可以用来检查两个对象引用是否指向同一个对象。
如果改为使用 const 声明,这就需要构造函数 Person 为常量构造函数,也就是在构造函数名之前加 const 关键字,然后所有属性都用 final 声明:

void main() {
  const p1 = Person('Jay');
  const p2 = Person('Jay');
  print(identical(p1, p2)); // true
  const p3 = Person('Eson');
  print(identical(p1, p3)); // false
}

class Person {
  final name;
  const Person(this.name);
}

这种情况下,如果传递给 Person() (前面省略了 const)的参数都相同,那么 p1p2 就是同一个对象。

其实在 dart 中,像下面这样使用 const 定义两个相同的数组,内存中也是只会保留一个对象的:

print(identical(const [1], const [1])); // true

大小写敏感

在 dart 中变量名大小写是敏感的,这个 js 一样。之前接触过的语言中只有 html 的标签和属性名或 css 中的代码对大小写不敏感。

默认值

在 js 中,用 varlet 声明一个变量,如果没有赋值,那么变量的默认值会是 undefined,而在 dart 中,使用 var 声明的变量默认值为 null

void main() {
  var name;
  print(name); // null
}

不会进行隐式转换

因为 dart 是强类型的语言,所以不会像 js 那样自动进行变量类型的隐式转换。

感谢.gif 点赞.png