缘起
在flutter论坛和社区,经常会出现针对关键字const的讨论。有的人在抱怨开发过程中会遇到一些场景让他们强制使用或者删除const,有的人则在赞美const关键字给他带来了性能的提升。
所以"const"到底是做什么的?在本文,我将分享我的认知和"实验心得"
const的重要性
当一个变量在编译时就确定而且以后不会再发生改变的时候,我们将使用const来修饰。换句话说,编译器事先知道该变量中存储什么值。
const int x =1;
当你只是声明和初始化一个const变量的时候,flutter也能自动推断出它的类型。-
const name = "John Doe";
但是以上这些并没有什么值得我们大惊小怪的?如果我使用const只是为了表明这个值是个常量,那我们为什么要过多的关注它呢?我们完全可以按照常规的方式去申明-
int x=1;
事实上,你也完全可以这样做,并且在上面这个例子里显然区别没那么明显。
「 const的实际用途只是作为一个标记,告诉编译器“这个变量在它的生命周期内是不会改变的,因此它只会创建一个副本,在使用的任何地方,都只是引用这个已经创建的副本而不会再new新的对象” 」
回到const的重要性讨论,我们知道flutter的界面由许多的Widget组成而每个Widget都对应一个类。假设我们要显示一个固定大小的蓝色方块
class BlueSquare extends StatelessWidget { final double size; BlueSquare({Key? key, required this.size}) : super(key: key); Widget build(BuildContext context) { return Container( height: size, width: size, color: Colors.blue, ); } }
当我们要显示100个大小为50的蓝色方块时,我们的通常做法是为100个对象每个都创建一个BlueSquare实例-
BlueSquare(size:50);
所以在这种场景下flutter会十分浪费的在内存中创建100个BlueSquare对象。但是是否能让它只创建一个,然后每当你尝试创建一个相同大小的新对象时,只是查找它的缓存并给你对象的引用?
因此const关键字在这个场景下就是有用的,当它遇到一个不会改变的构造函数,换句话说,一个常量构造函数时,它会告诉flutter要做什么。
如果你不在构造函数前面添加const关键字,那么即使它满足const条件,flutter也不会自动去处理这件事,当然我们也不能用const去初始化它。因此让我们需要将上面的例子稍做修改
class BlueSquare extends StatelessWidget { final double size; →→ const BlueSquare({Key? key, required this.size}) : super(key: key); Widget build(BuildContext context) { return Container( height: size, width: size, color: Colors.blue, ); } }
然后在创建对象的地方改为
const BlueSquare(size: 50);
最后在做一个简单的验证
y = const BlueSquare(size: 50); x = const BlueSquare(size: 50); x==y // true,true,true重要的事情说三遍
事实上const的重要性并不仅仅在节约内存上。当一个对象被标记成常量时,flutter在rebuild的时候知道它是不变的,进而节省rebuild的时间,加快页面的显示。
关于final
简单说一下final。因为在讨论const的时候总是绕不开的"被提及final"。因为许多开发人员经常混淆使用final和const。
final int x = 50; const int x = 50;
const和final实际上非常相似,因为它们都定义了不可更改的值。但是final更像是"不那么严格的const"。final可以在编译后一段时间内不确定其值直到它被赋值。
final response = await http.get(Uri.parse(‘https://baidu.com'));
总结
1. const在某些场景可以节约内存,加速页面rebuild时间。
2. final可以理解为"不那么严格的const"。
查看更多关于谈谈flutter关键字const的详细内容...