Flutter 小技巧之为什么推荐 Widget 使用 const

今天收到这个问题,本来想着简单回复下,但是感觉这个话题又可以稍微展开讲讲,干脆就整理成一篇简单的科普,这样也能更方便清晰地回答这个问题。

聊这个问题之前,我们需要把一个“老生常谈”的概念拿出来说,那就是:Flutter 里 Widget 是不可变的,它不是真正的 View,Widget 只是一个「配置文件」的作用

后面只有基于这个概念,结合 const 的「深度不变性」 ,才能更全面理解为什么 Flutter 中推荐 Widget 使用 const 。

Dart 里的 final & const

我们先简单过一遍 Dart 里的 final 和 const 的区别,要解答开头那个问题,只讲 const 明显是不够,在 Dart 里:

  • final :变量只能赋值一次,值在运行时确定

  • const:变量必须是编译时常量,值在编译时已知

虽然都是「不可变」声明,但是对于 Dart 来说,final 和 const 最大的区别就在于一个是运行时确定,一个是编译时确定。

final

针对 final , final 虽然也不可变 ,但是它的值可以在运行时确定,同时它还允许延迟初始化(late),如下代码所示:

  • 变量 a 可以是 late final
  • result 的数可以是通过 doSomeThing 返回
late final String a;void runResult() {final int result = doSomeThing(); 
} 

也就是 final 可以在运行时赋值,之后就不可以改变,类似场景就可以对应在 Widget 的构造函数上,通过 final 关键字创建不可变的实例变量,这些变量在构造函数级别初始化,并且对于每个类实例都是唯一的:因为 Flutter 里 Widget 是不可变的,所以对于 Widget 来说,它内部的变量也应该是不可变

class MyHomePage extends StatelessWidget {MyHomePage({super.key, this.title});final String? title;
}

const

const 属于编译时不可变声明,可以理解为它是比 final 更高级的 「深度不变」,也就是编译时就确定了它的值,所以它会有更好的性能优势,例如:

  • 作为编译时常量的, const 变量在编译时已知,因此它在编译期间只会被“评估”一次,这意味着 Dart 编译器可以对它们进行优化,从而节省内存并缩短需要的启动时间
  • 当 const 变量在不同位置使用时,Dart 编译器只会给它分配一次空间,并且该值将在引用它的其他位置重复使用。

从这个角度理解,const 确实可以一定程度提高性能和节约内存 ,再举个典型例子解释下 「深度不变」,如下代码所示:

可以看到通过 const 声明的 list, 它内部的 item 也是在编译时确定,并且是不允许被修改,不仅列表本身是一个编译时常量,它内部每个元素也是编译时常量。

const List<int> list = [0,0,0,0,0,0];list[2] = 3;

而对于 class 而言,const 声明的构造函数,会被要求内部变量需要使用 final 声明,从而确保对象是可传递的不可变的,这样就可以保证静态数据的完整,并且对象一旦设置就无法被篡改。

class Test {final int a;const Test(this.a);
}void runTest() {const Test test = Test(0);test.a = 100;  /// error
} 

这个看起来是不是很眼熟?对,没错,就是 Flutter 里的 Widget,当 Widget 的构造函数是 const 的时候,它内部的变量都需要时 final ,不然就会在编译时报错。

class MyHomePage extends StatelessWidget {const MyHomePage({super.key, this.title});final String? title;
}

如果没有 const ,默认规则下只会是警告:This class (or a class that this class inherits from) is marked as ‘@immutable’, but one or more of its instance fields aren’t final

另外,const 声明的构造函数,对于 class 来说也会在编译时优化,如下代码所示,可以看到它们都在编译期得到了优化:

  • test 1 和 test 2 的 hashCode 是一样的
  • test 3 和 test 4 的 hashCode 是一样的
  class Test {final int a;final int b;const Test(this.a, this.b);}void runTest() {const Test test1 = Test(0, 0);print("test1 hash code is: ${test1.hashCode}");const Test test2 = Test(0, 0);print("test2 hash code is: ${test2.hashCode}");const Test test3 = Test(1, 1);print("test3 hash code is: ${test3.hashCode}");const Test test4 = Test(1, 1);print("test4 hash code is: ${test4.hashCode}");const Test test5 = Test(2, 2);print("test5 hash code is: ${test5.hashCode}");}

Flutter

那么回到最初的问题,因为 Flutter 里的 Widget 不是真正的 View ,它只是个配置文件,背后是 Element 和 RenderObject 实体在工作,所以对于「不可变」的 Widget 来说,const 去声明一个「配置文件」做优化,明显可以提高性能和减少内存占用。

至于为什么说 Widget 不是真正的 View , 详细的可以看我以前的文章,这里简单展示一个我经常提到的例子,如下代码所示,textUseAll 如果是一个真正的 View ,它是不能同时被多个地方添加,从这个例子可以更直观体现 Widget 是配置信息的作用。

对于 Flutter 来说,Flutter 会严重依赖 Widget 树的 「配置信息」来表示 UI,在 rebuild 期间遇到标记为const 的 Widget 时,Flutter 会将其识别为预构建且不可变的对象 ,这个情况下, Flutter 可以重复使用现有对象,而不必创建新对象,这种重复使用可避免不必要的计算和对象分配。

同时前面提到过,const 在编译时会执行优化,这些优化包括前面提到的预分配内存和常量折叠,这意味着在运行时可以更快地创建对象并减少垃圾回收触发。

另外,对于 Widget Tree 来说,const 可以确保只有当它们的引用实际发生变化时才会 rebuild,进而减少了不必要的 Widget 创建和重构。

所以,是不是无用知识又增长了?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Open3d 点云投影到 xoy yoz 平面最简单的方式(附python 代码)

最简单的方式&#xff0c;就是直接把原有的点云的数据的 z or x 赋值为0, 然后生成一个新的点云。 filename_model1 r"1.pcd"down 10point_cloud o3d.io.read_point_cloud(filename_model1) point_cloud point_cloud.uniform_down_sample(int(down)) print(降采样…

metasfresh开源ERP系统Windows开发环境配置参考

目录 概述 开发环境 配置过程 后端启动 前端启动 登陆系统 其他 概述 Compiere闭源之后衍生出了Admpiere等若干开源的产品&#xff0c;metasfresh就是其中之一&#xff0c;metasfresh截至发稿时在GitHub上已有64000多次的修改提交&#xff0c;而且仍在维护中&#xff0…

GIS避坑指南!工作中ArcGIS常用的40个小技巧

01图斑的边界线太粗而且无法修改 之前有群友遇到这样一个问题&#xff0c;边界线粗到连图斑都看不见&#xff1a; 查看符号系统&#xff0c;很正常&#xff1a; 究其原因&#xff0c;是地图视图比例的问题&#xff0c;正常情况下&#xff0c;地图的视图比例会随着视图范围自动调…

未来20年人工智能将如何塑造社会

照片由Brian McGowan在Unsplash上拍摄 更多资讯&#xff0c;请访问 2img.ai “人工智能会成为我们的救星还是我们的末日&#xff1f;” 几十年来&#xff0c;这个问题一直困扰着哲学家、科学家和科幻爱好者。 当我们踏上技术革命的边缘时&#xff0c;是时候透过水晶球&#x…

我国氮化硼市场规模逐渐扩大 市场集中度有望不断提升

我国氮化硼市场规模逐渐扩大 市场集中度有望不断提升 氮化硼&#xff08;BN&#xff09;俗称为白石墨&#xff0c;是由硼原子和氮原子所构成的一种晶体材料&#xff0c;在常温条件下多表现为一种棕色或暗红色晶体。氮化硼具有导热性好、硬度大、熔点高、抗化学侵蚀性等优点&…

快来看,错过了今天就要设置为vip文章了----openEuler@2024全球发展展望与战略规划

会议主题&#xff1a;openEuler2024全球发展展望与战略规划 OpenEuler2024项目在2024年成功推出了多个长期支持&#xff08;LTS&#xff09;版本&#xff0c;标志着其在智能技术领域的全新篇章&#xff0c;并致力于构建全球性的开源新生态。以下是该项目的主要内容和成就概览&a…

【日记】软考居然一次过了(620 字)

正文 早上空闲的时候&#xff0c;上 QQ 看了一下&#xff0c;许久不见动静的系统架构设计师群有人说出分了。我想高级都出分了&#xff0c;中级应该也出来了&#xff0c;于是用手机查了一下。看到分数几乎快要泪从中来。为什么软考能一次过&#xff0c;银行从业资格证考了两三…

MST霍尔传感器IC-MH251,MH253,GT3144在卷发器方案中的应用

霍尔传感器驱动卷发器应用 卷发器在我们的日常生活中已经成为了不可或缺的一种生活工具&#xff0c;它时刻可以护理我们的头发&#xff0c;保养我们的发质。霍尔传感器驱动卷发器&#xff0c;那么霍尔传感器是如何运用在卷发器中的呢&#xff1f;霍尔传感器在卷发器中的工作原…

快速阅读参考文献:kimi请求出战!

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 上篇文章&#xff0c;我们为大家演示了“如何使用kimi创建论文中的流程图”。今天继续为大家介绍“使用kimi快速阅读学术参考文献”。 在学术研究的海洋中&#xff0c;文献阅读是一项基…

Windows环境下安装MySQL数据库的步骤

说明&#xff1a; 由于环境的不同&#xff0c;安装过程中可能会遇到各种各样的问题&#xff0c;不用慌&#xff0c;先根据错误提示搜索&#xff0c;多试一下。 安装前&#xff0c;请先认真看一下&#xff0c;有可能会遇到的几个问题&#xff1a; 1、证书链问题&#xff0c;一般…

【投稿优惠|稳定检索】2024年文化传播、交流与考古学国际会议 (CCEA 2024)

2024年文化传播、交流与考古学国际会议 (CCEA 2024) 2024 International Conference on Cultural Communication, Exchange, and Archaeology 【重要信息】 大会地点&#xff1a;西安 官网地址&#xff1a;http://www.icccea.com 投稿邮箱&#xff1a;iccceasub-conf.com 【注…

阿里1688商家数据采集软件

大镜山阿里1688商家数据采集一款采集阿里巴巴1688.com商家数据的软件&#xff0c;采集的数据包括店铺名称、联系人姓名、手机号码等。 一、大镜山阿里1688商家数据采集特色 — 大镜山阿里1688商家数据采集一款采集阿里巴巴1688.com商家数据的软件&#xff0c;采集的数据包括店…

一键系统重装教程:电脑重装系统,5个方法轻松恢复电脑

在日常使用电脑的过程中&#xff0c;难免会遇到系统故障、运行缓慢或者病毒感染等问题&#xff0c;重装系统成为解决这些问题的有效途径。然而&#xff0c;对于许多小伙伴来说&#xff0c;电脑重装系统似乎是一项复杂且耗时的任务。其实&#xff0c;只要掌握了正确的方法&#…

深圳比创达电子|EMC与EMI测试整改:从问题识别到效果验证

在现代电子设备的研发和生产过程中&#xff0c;电磁兼容性&#xff08;EMC&#xff09;和电磁干扰&#xff08;EMI&#xff09;的问题日益凸显。随着技术的不断进步&#xff0c;电子设备的集成度越来越高&#xff0c;工作频率也逐步提升&#xff0c;这使得电磁环境的复杂性不断…

自研一款共享集群数据库,有多难?

共享集群数据库管理系统是一种单库多实例的多活数据库管理系统&#xff0c;用户连接任意实例都可以访问同一个数据库&#xff0c;具备透明多写、高可用、高性能等特性。共享集群技术因其开发难度高&#xff0c;一直被国外垄断&#xff0c;也被称为数据库领域的“塔尖”技术。 2…

不会还有人没有用过git rebase合并分支吧?一文详解git merge与git rebase区别

文章目录 什么是git merge&#xff1f;使用git merge的场景git merge的示例 什么是git rebase&#xff1f;使用git rebase的场景git rebase的示例 git merge与git rebase的区别如何选择git merge和git rebase&#xff1f;结论 &#x1f389;欢迎来到Java学习路线专栏~探索Java中…

vscode的一些使用问题

vscode使用技巧 1、快捷键&#xff08;1&#xff09;打开命令面板&#xff08;2&#xff09;注释&#xff08;3&#xff09;删除行&#xff08;4&#xff09;上下移动光标&#xff08;5&#xff09;光标回退&#xff08;6&#xff09;复制行&#xff08;7&#xff09;插入空白行…

[计算机网络] 虚拟局域网

虚拟局域网 VLAN&#xff08;Virtual Local Area Network&#xff0c;虚拟局域网&#xff09;是将一个物理的局域网在逻辑上划分成多个广播域的技术。 通过在交换机上配置VLAN&#xff0c;可以实现在同一个VLAN 内的用户可以进行二层互访&#xff0c;而不同VLAN 间的用户被二…

VMware Workstation环境下,邮件(E-Mail)服务的安装配置,并用Windows7来验证测试

需求说明: 某企业信息中心计划使用IP地址17216.11.0用于虚拟网络测试,注册域名为xyz.net.cn.并将172.16.11.2作为主域名的服务器(DNS服务器)的IP地址,将172.16.11.3分配给虚拟网络测试的DHCP服务器,将172.16.11.4分配给虚拟网络测试的web服务器,将172.16.11.5分配给FTP服务器…

如何给WPS、Word、PPT等办公三件套添加收费字体---方正仿宋GBK

1.先下载需要的字体。 下载字体的网站比较多&#xff0c;基本上都是免费的。随便在网上搜索一个就可以了&#xff0c;下面是下载的链接。 方正仿宋GBK字体免费下载和在线预览-字体天下 ​www.fonts.net.cn/font-31602268591.html 注意&#xff1a;切记不要商用&#xff0c;以免…