Fluter学习3 - Dart 空安全

Dart 空安全:

  • 空类型操作符 (?)
  • 空值合并操作符 (??)
  • 空值断言操作符 (!)
  • 延迟初始化 (late)

1、空类型操作符 (?)

  • 当你想要根据一个表达式是否为 null 来执行某个操作时,你可以使用 (?)
  • 语法:expression1?.expression2
  • 如果 expression1 不是 null,则执行 expression2 并返回其结果。如果 expression1 是 null,则直接返回 null,并且不会执行 expression2。
void main(){
  String? name = null;
  int? length = name?.length;
  print("length: $length");  //length: null
}
// 如果 name 是 null,length 也会是 null  
// 如果 name 不是 null,length 将会是 name 的长度

2、空值合并操作符 (??)

  • 当你想要为一个可能为 null 的表达式提供一个默认值时,你可以使用 (??)
  • 语法:expression1 ?? expression2
  • 如果 expression1 不是 null,则返回 expression1 的值。如果 expression1 是 null,则返回 expression2 的值。
void main() {
  String? name = null;
  String fullName = name ?? "Unknown";
  print("fullName: $fullName"); //fullName: Unknown
}
// 如果 name 是 null,则 fullName 为 "Unknown"
// 如果 name 不是 null,则 fullName 为 name 的值

3、空值断言操作符 (!)

  • 当你确定一个表达式不应该为 null,但编译器无法确定时,你可以使用!来告诉编译器你确信该表达式不是 null
  • 语法:expression!
  • 使用此操作符时,你应确保表达式确实不是 null,否则在运行时会出现 NullPointerException
void main() {
  String? name = null;
  int length = name!.length;
  print("length: $length"); //Unhandled exception:Null check operator used on a null value
}
// 确信 name 不是 null,并获取其长度
// 如果 name 是 null,则会报错 NullPointerException
补充,(!) 取反用法
void main(){

  String name = "leon";

  if(name is! String){
    print("其他类型");
  }else{
    print("String类型");
  }
}
//输出:String类型

4、延迟初始化 (late)

  • 当你在声明变量时使用 late 关键字,你告诉 Dart 编译器该变量将在稍后的某个时间点被初始化,而不是在声明时立即初始化
void main() {  
  late String name; // 声明一个late变量,此时不需要初始化  
  
  if (someCondition) {  
    name = 'Alice'; // 在某个条件满足时进行初始化  
  } else {  
    name = 'Bob'; // 在另一个条件满足时进行初始化  
  }  
  
  print(name); // 使用已经初始化的变量  
}  
  
bool someCondition = true; // 假设这是某个条件,实际情况中可能根据逻辑判断来设置
  • 在 Flutter 中 State 的 initState 方法中初始化的一些变量,是比较适合使用 late 来进行延时初始化的
  • 因为在 Widget 生命周期中 initState 方法是最先执行的,所以它里面初始化的变量通过 late 修饰后既能保障使用时的便利,又能防止空异常
class _TravelPgeState extends State<TravelPge> with TickerProviderStateMixin {

  late TabController _controller;
  
  
  void initState() {
    super.initState();
    _controller = TabController(length: 0, vsync: this);
  }
  ...

5、补充:Widget 生命周期

  • 在 Flutter 中,Widget 并不直接具有生命周期,因为 Widget 是不可变的(immutable)
  • 然而,Flutter 中的 StatefulWidget 和 State 对象确实具有生命周期,因为 StatefulWidget 可以创建和管理一个可变的状态对象(State)

当你插入一个 StatefulWidget 到 Flutter 的 widget 树时,Flutter 会进行以下操作:

创建(Create):
  • StatefulWidget 的实例被创建
  • createState() 方法被调用以创建一个新的 State 对象
  • initState() 方法在 State 对象上被调用,你可以在这里进行初始化操作
插入(Insert):
  • StatefulWidget 和它的 State 对象被插入到 widget 树中
  • build() 方法在 State 对象上被调用,以构建 widget 树
更新(Update):
  • 当 StatefulWidget 的依赖项发生变化时,Flutter 会重新构建 widget 树
  • build() 方法会再次被调用,但 State 对象不会改变
  • 如果你想根据新的依赖项更新 State,你可以调用 setState(() {}),这将导致 build() 方法再次被调用,但 initState() 不会被调用
移除(Remove):
  • 当 StatefulWidget 从 widget 树中移除时,Flutter 会调用 dispose() 方法。你可以在这里释放任何资源或执行任何必要的清理操作

注意,build() 方法在整个生命周期中可能会被多次调用,而 initState() 和 dispose() 方法每个 State 对象只会被调用一次。

class LifecycleWidget extends StatefulWidget {  
    
  _LifecycleWidgetState createState() => _LifecycleWidgetState();  
}  
  
class _LifecycleWidgetState extends State<LifecycleWidget> {  
    
  void initState() {  
    super.initState();  
    print('initState called');  
    // 初始化代码  
  }  
  
    
  Widget build(BuildContext context) {  
    print('build called');  
    return Container(  
      padding: const EdgeInsets.all(16.0),  
      child: Text('Lifecycle Widget'),  
    );  
  }  
  
    
  void dispose() {  
    super.dispose();  
    print('dispose called');  
    // 清理代码  
  }  
}
  • 在这个例子中,当你插入 LifecycleWidget 到 Flutter 应用中时,你会看到 “initState called” 和 “build called” 打印出来
  • 如果依赖项发生变化并触发重建,只有 “build called” 会再次打印
  • 当你从 widget 树中移除 LifecycleWidget 时,“dispose called” 会打印出来。

6、空安全适配示例

(1)示例1

  • 空类型:(?) 修饰
  • 非空类型:1)定义时初始化 2)(late) 延迟初始化

非空类型需要在构造函数中指定 required

void main() {
  Person person = Person(name: "leon", sex: "man");
  person.display();
  person.setAge(27);
  person.display();
}

class Person {
  String name = ""; //非空类型,定义时初始化
  int? age; //空类型,(?) 修饰
  late String sex; //非空类型,(late) 延迟初始化

  //非空类型需要在构造函数中指定 required
  Person({required this.name, required this.sex});

  void setAge(int age) {
    this.age = age;
  }

  void display() {
    print("name: $name  age: $age  sex: $sex");
  }
}

(2)示例2

  • State中延迟初始化的属性,可以在 initState() 中赋值

在这里插入图片描述

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'muke flutter',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: const MyHomePage(title: 'muke learning'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({super.key, required this.title});

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late String data; //延迟初始化

  //State中延迟初始化的属性,可以在 initState() 中赋值
  
  void initState() {
    super.initState();
    data = "延迟初始化";
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(child: Text("data: $data")));
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于开放系统互联的一些笔记

最近几天就发几篇计算机方面的基础知识 属于个人归纳整理&#xff0c;便于理解希望对大家有帮助 原文地址&#xff1a;关于开放系统互联的一些笔记 - Pleasure的博客 下面是正文内容&#xff1a; 前言 最近在恶补一些计算机方面的基础知识…… 正文 首先为了能够更透彻的理…

c语言结构体与共用体

前面我们介绍了基本的数据类型 在c语言中 有一种特殊的数据类型 由程序员来定义类型 目录 一结构体 1.1概述 1.2定义结构体 1.3 结构体变量的初始化 1.4 访问结构体的成员 1.5结构体作为函数的参数 1.6指向结构的指针 1.7结构体大小的计算 二共用体 2.1概述 2.2 访…

智慧安防/视频监控汇聚平台EasyCVR如何通过接口调用获取设备录像回看的流地址?

视频云存储/视频融合/安防监控EasyCVR视频汇聚系统可兼容各品牌的IPC、NVR、移动单兵、智能手持终端、移动执法仪、无人机、布控球等设备的接入&#xff0c;支持的接入协议包括&#xff1a;国标GB28181、RTSP/Onvif、RTMP&#xff0c;以及厂家的私有协议与SDK&#xff0c;如&am…

探索在GIS中使用ChatGPT

在创建了一个简单的点击询问 ChatGPT GIS 应用程序之后&#xff0c;我一直在努力想出关于如何在 GIS 应用程序中使用 ChatGPT 和 OpenAI 的更好的主意。后来想到只需要要问问 ChatGPT “如何使用它”&#xff0c;下面是对其中的几个实例。 简单的点击询问应用程序 地理输入和输…

最大划水收益

解法&#xff1a; 双指针、贪心 #include <iostream> #include <vector> using namespace std; #define endl \nint main() {ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int n, k;cin >> n >> k;vector<int> vec(n, 0);for (int i …

你所在的行业,有必要做小程序么?

引言 在当今数字化飞速发展的时代&#xff0c;企业和行业正面临着不断变化的市场环境。随着移动互联网的崛起&#xff0c;小程序作为一种轻量级、便捷的应用形式&#xff0c;逐渐成为各行各业提升服务效率、拓展市场份额的重要工具。对于你所在的行业&#xff0c;究竟是否有必…

【深度优先搜索】【树】【状态压缩】2791. 树中可以形成回文的路径数

作者推荐 【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II 本文涉及知识点 深度优先搜索 树 图论 状态压缩 LeetCode:2791. 树中可以形成回文的路径数 给你一棵 树&#xff08;即&#xff0c;一个连通、无向且无环的图&#xff09;&#xff0c;根 节点为 0 &am…

Javascript怎么输出内容?两种常见方式以及控制台介绍

javascript是一种非常重要的编程语言&#xff0c;在许多网页中它被广泛使用&#xff0c;可以实现许多交互效果和动态效果。输出是javascript中最基本的操作之一&#xff0c;下面将介绍两种常见的输出方式。 一、使用console.log()函数输出 console.log()函数是常用的输出函数…

【牛客面试必刷TOP101】Day24.BM34 判断是不是二叉搜索树和BM35 判断是不是完全二叉树

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;牛客面试必刷TOP101 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&…

3d模型导出fbx面出错是什么原因?怎么解决---模大狮模型网

3D模型在导出为FBX格式时出错可能有多种原因&#xff0c;以下是一些常见的原因和解决方法&#xff1a; 一&#xff1a;模型包含不支持的元素 某些特定的元素或功能在导出为FBX格式时可能会导致错误。例如&#xff0c;某些软件中使用了特殊的插件、约束或动画效果&#xff0c;这…

【学习笔记】数据结构与算法04:哈希表、哈希冲突、哈希算法

知识出处&#xff1a;Hello算法&#xff1a;https://www.hello-algo.com/ 文章目录 2.3 哈希表2.3.1 哈希表「 hash table」2.3.1.1 哈希表常见操作2.3.1.2 哈希表的简单实现2.3.1.3 哈希冲突与扩容 2.3.2 哈希冲突2.3.2.1 「链式地址 separate chaining」2.3.2.2 「开放寻址 o…

数字革命的先锋:探索Web3的无限可能性

随着科技的不断进步&#xff0c;我们正在迎来数字革命的新时代。在这个时代中&#xff0c;Web3技术作为数字革命的先锋&#xff0c;正以其独特的特点和无限的可能性引领着未来的发展方向。本文将深入探索Web3技术的核心原理、应用场景以及对未来的影响&#xff0c;揭示数字革命…

32看门狗

目录 一.看门狗简介 二&#xff0e;代码实现 一.看门狗简介 IWDG的专用时钟是LSI&#xff0c;内部低速时钟 WWDG使用的是APB&#xff11;的时钟&#xff0c;并没有专门的时钟&#xff0c;所以并不独立 如果独立看门狗已经由硬件选项或软件启动&#xff0c; LSI振荡器将被强制…

Aster实现一台电脑当两台使——副屏搭配键鼠

前言&#xff1a;笔者每年回家&#xff0c;都面临着想要和小伙伴一起玩游戏&#xff0c;但小伙伴没有电脑/只有低配电脑的问题。与此同时&#xff0c;笔者自身的电脑是高配置的电脑&#xff0c;因此笔者想到&#xff0c;能否在自己的电脑上运行游戏&#xff0c;在小伙伴的电脑上…

C++从入门到精通 第十二章(C++流)

一、C流的概念 1、C流的体系结构 &#xff08;1&#xff09;C为实现数据的输入输出定义了一系列的流类&#xff0c;这些类之间的派生、继承关系如下图所示&#xff0c;它们之中一部分是用模板实现的&#xff0c;图中用细线框表示&#xff0c;另外图中的虚线表示模板类与模板实…

计算机二级C语言的注意事项及相应真题-5-程序修改

目录 41.累加链表结点数据域中的数据作为函数值返回42.根据整型形参m&#xff0c;计算如下公式的值43.删除数列中值为x的元素44.从N个字符串中找出最长的那个串&#xff0c;并将其地址作为函数值返回45.将两个长度相等的纯数字字符串当作两个加数&#xff0c;求其代表的数值之和…

【Docker】Linux主机部署Docker

Docker部署 1.二进制文件部署 到如下地址&#xff0c;下载二进制包。 Docker官网&#xff1a;https://docs.docker.com/engine/install/binaries/ 网易镜像源&#xff1a;https://mirrors.163.com/docker-ce/linux/static/stable/x86_64/ 下载好的二进制包上传到主机&#xf…

C++项目 -- 高并发内存池(七)性能瓶颈与优化

C项目 – 高并发内存池&#xff08;七&#xff09;性能瓶颈与优化 文章目录 C项目 -- 高并发内存池&#xff08;七&#xff09;性能瓶颈与优化一、检测性能瓶颈二、使用基数树来优化项目1.基数树2.不加锁的原理3.性能对比 三、最终代码实现 一、检测性能瓶颈 DeBug下运行代码&…

015—pandas 标记按月连续变化趋势

前言 在业务数据分析中&#xff0c;特别是和时间相关的数据&#xff0c;会经常要判断数据的变化情况&#xff0c;比如是否是增长还是降低&#xff0c;或是持平。 需求 以数据中最后的月份为基础&#xff0c;来看它最近的数据变化&#xff0c;并将变化情况标记在本行的最后一…

网络基础与通信原理:构建数字世界的框架

目录 初识计算机网络 网络介绍 按照拓扑分类 按地域分类 网络设备 交换机&#xff08;switch&#xff09; 路由器&#xff08;router&#xff09; 传输介质 双绞线 光纤 光纤速度 ISO ISO和OSI有什么关系呢&#xff1f; OSI七层模型 TCP/IP四层 TCP/IP协议族 …