我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123… 。
今天继续学习 Flutter 的编程语言 Dart 的语法基础,主要是关于注释和变量这两方面的内容。
注释
注释分成 3 种:
- 单行注释
使用 //,同 js 是一样的:
// 我是单行注释
- 多行注释
多行注释以 /* 开始,以 */ 结尾,也与 js 一样:
/*
我是多行
注释
*/
- 文档注释
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 的区别
既然 final 和 const 都是用来声明常量的,那它们之间有什么区别呢?
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 声明的 p1 和 p2,都通过 Person('Jay')(前面省略了 new)得到,传入的参数是一样的,但是 p1 和 p2 却并不是同一个对象,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)的参数都相同,那么 p1 和 p2 就是同一个对象。
其实在 dart 中,像下面这样使用 const 定义两个相同的数组,内存中也是只会保留一个对象的:
print(identical(const [1], const [1])); // true
大小写敏感
在 dart 中变量名大小写是敏感的,这个 js 一样。之前接触过的语言中只有 html 的标签和属性名或 css 中的代码对大小写不敏感。
默认值
在 js 中,用 var 或 let 声明一个变量,如果没有赋值,那么变量的默认值会是 undefined,而在 dart 中,使用 var 声明的变量默认值为 null:
void main() {
var name;
print(name); // null
}
不会进行隐式转换
因为 dart 是强类型的语言,所以不会像 js 那样自动进行变量类型的隐式转换。
