flutter学习-day3-dart基础

📚 目录

  1. 变量声明
  2. 操作符
  3. 数据类型
  4. 控制流
  5. 错误处理和捕获
  6. 函数
  7. mixin
  8. 异步
    1. Future
    2. Stream

本文学习和引用自《Flutter实战·第二版》:作者:杜文

1. 变量声明

  • var

类似于 JavaScript 中的var,它可以接收任何类型的变量,但最大的不同是 Dart 中 var 变量一旦赋值,类型便会确定,则不能再改变其类型:

var name = "李四"
/// 对
name = "张三"
/// 错
name = 1000
  • Object

Object 是 Dart 所有对象的根基类,也就是说在 Dart 中所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象,且后期可以改变赋值的类型。但是声明的对象只能使用 Object 的属性与方法, 否则编译器会报错。

Object t = 1000t = "张三"print(t.length) // 错
  • dynamic

任何类型的数据都可以赋值给dynamic声明的对象,且声明的变量都可以赋值任意对象,且后期可以改变赋值的类型。而编译器会提供所有可能的组合给声明的对象,这个特点使得我们在使用它时需要格外注意,比如下面代码在编译时不会报错,而在运行时会报错:

dynamic tt = "王五"print(t.xxx) // 错
  • final

如果您从未打算更改一个变量,那么可以使用 final。一个 final 变量只能被设置一次。它是一个运行时常量,final变量在运行时才知道其值,用于防止变量在程序运行期间被改变。

  • const

如果您从未打算更改一个变量,那么可以使用 const。与final的区别是,const 变量是一个编译时常量,其值必须在声明时就确定。(编译时直接替换为常量值)用于创建编译时常量,以便进行性能优化。

  • 空安全

Dart 中一切都是对象,这意味着如果我们定义一个数字,在初始化它之前如果我们使用了它,假如没有某种检查机制,则不会报错。如下:

test() {int i; print(i*8); // 错
}

在 Dart 引入空安全之后,如果一个变量没有初始化,则不能使用它,否则编译器会报错:

int a = 10

声明时候可以加上?,指定变量是可空:

String? name;

如果我们预期变量不能为空,但在定义时不能确定其初始值,则可以加上late关键字,表示会稍后初始化,但是在正式使用它之前必须得保证初始化过了,否则会报错:

late int c;c = 100

如果一个变量我们定义为可空类型,且判空了,但是预处理器仍然有可能识别不出,这时我们就要在变量后面加一个!符号,告诉预处理器它已经不是null了。

class Test() {int? d;log() {if (d! = null) {print(d! * 100)}}
}

如果函数变量可空时,调用的时候可以用语法糖:

fun?.call()
  • 特殊声明模式
// 同时声明
var (a, [b, c]) = ('str', [1, 2])// 同时声明
var (c, d) = ('left', 'right');// 交换2个值
(c, d)  = (d, c)// 解构
var (name, age) = userInfo(json)// 省略符 
var (a, b, ...rest) = [1, 2, 3, 4, 5, 6] // 1 2 [3,4,5,6]var (a, b, ...rest, c, d) = [1, 2, 3, 4, 5, 6] // 1 2 [3,4] 5 6var (a, b, ..., c, d) = [1, 2, 3, 4, 5, 6] // 1 2 5 6

2. 操作符

  • 算数运算符
符号意义描述
+-
--
*-
/-
~/返回整数结果
%取余获取整数除法的余数
  • 等于运算符
符号意义描述
==平等-
!=不相等-
>大于-
<小于-
>=大于或等于-
<=小于或等于-
  • 逻辑运算符
符号意义描述
!反转-
||或者-
&&并且-
  • 赋值运算符
符号意义描述
=赋值-
*=乘法赋值-
+=加法赋值-
-=减法赋值-
/=除法赋值-
%=取模赋值-
~/=返回除法整数结果赋值-
=按位或赋值
&=按位与赋值-
^=按位异或赋值-
<<=左移赋值-
>>=右移赋值(保留符号位)-
>>>=右移赋值(无符号右移)-
  • 类型运算符
符号意义描述
as类型转换断言-
is如果对象具有指定的类型,则为 True-
is!如果对象没有指定的类型,则为 True-
// 如果您不确定该对象的类型是否为Person,则在使用对象之前用is检查
if (employee is Person) {employee.firstName = 'Bob';
}
  • 按位运算符
符号意义描述
&-
|-
^异或-
<<左移-
>>右移-
>>>无符号右移-
  • 条件表达式
语法意义描述
condition ? expr1 : expr2赋值三元表达式
expr1 ?? expr2赋值如果 expr1 为非 null,则返回其值; 否则,计算并返回 expr2 的值
?.xxx短路条件成员访问
!断言将表达式强制转换为其基础不可为 null 的类型
  • 级联表示法

级联允许您在同一对象上,进行一系列操作。

// 级联语法
var paint = Paint()..color = Colors.black..strokeCap = StrokeCap.round..strokeWidth = 5.0;// 等价于如下语法
var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;
// 级联语法
querySelector('#confirm')?..text = 'Confirm'..classes.add('important')..onClick.listen((e) => window.alert('Confirmed!'))..scrollIntoView();// 等价于如下语法
var button = querySelector('#confirm');
button?.text = 'Confirm';
button?.classes.add('important');
button?.onClick.listen((e) => window.alert('Confirmed!'));
button?.scrollIntoView();

3. 数据类型

关键字描述
int不大于 64 位的整数值
double64 位(双精度)浮点数
String字符串,多行字符串可以用’‘‘xxx’’’
bool字符串
Set
Map地图
List列表
Symbol符号
Nullnull
record记录
typedef类型别名

4. 控制流

  • switch
int size = 2;// 条件判断
switch (size) {case 1:print('一');case [2, 3]:print('二 and 三')case [4 || 5]:print('四 or 五')case >= 6 && <= 10print('六 to 十')
}// 条件赋值
var bg = Color.greenvar isPrimary = switch (bg) {Color.red || Color.yellow || Color.blue => true,_ => false
}
  • for
var message = StringBuffer('Dart is fun');for (var i = 0; i < 5; i++) {message.write('!');
}
  • fon-in
Map<String, int> listMap = {'a': 23,'b': 100,
};for (final MapEntry(key: key, value: value) in listMap.entries) {print('键:$key 值:$value');
}
  • while
while (!isDone()) {doSomething();
}
  • do-while
do {printLine();
} while (!atEndOfPage());
  • 跳过和停止
while (true) {if (shutDownRequested()) break;processIncomingRequests();
}for (int i = 0; i < candidates.length; i++) {var candidate = candidates[i];if (candidate.yearsExperience < 5) {continue;}candidate.interview();
}
  • if
if (isRaining()) {you.bringRainCoat();
} else if (isSnowing()) {you.wearJacket();
} else {car.putTopDown();
}
  • if-case
// 接受一个名为pair的参数。如果pair的类型是[int x, int y],则返回一个Point(x, y)对象
if (pair case [int x, int y]) return Point(x, y);

5. 错误处理和捕获

异常捕获和JavaScript差不多

try {breedMoreLlamas();
} on OutOfLlamasException {// 特定的异常buyMoreLlamas();
} on Exception catch (e) {// 任何其他的例外print('Unknown exception: $e');
} catch (e) {// 没有指定类型,处理所有类型print('Something really unknown: $e');
} finally {cleanLlamaStalls();
}
  • 若要部分处理异常, 同时允许它传播, 使用关键字:rethrow
void misbehave() {try {dynamic foo = true;print(foo++); // 运行时错误} catch (e) {print('misbehave() partially handled ${e.runtimeType}.');rethrow; // 允许调用者看到异常}
}void main() {try {misbehave();} catch (e) {print('main() finished handling ${e.runtimeType}.');}
}
  • 断言

在开发过程中,使用断言语句,如果布尔条件为false,则触发。如果条件为true,则不触发。在生产代码中,断言将被忽略。

// assert(条件, 可选消息)
var sizi = 101;
assert(size < 100, "Error:size 小于 100!");

6. 函数

Dart是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型Function。这意味着函数可以赋值给变量或作为参数传递给其他函数,这是函数式编程的典型特征。

  • 函数声明
bool isNoble(int ) {return atomicNumber > 40;
}bool isNoble (int atomicNumber) => atomicNumber > 40;
  • 函数作为参数传递
//定义函数execute,它的参数类型为函数
void execute(var callback) {// 执行传入的函数callback();
}// 调用execute,将箭头函数作为参数传递
execute(() => print("xxx"))
  • 可选的位置参数
String say(String a, String b, [String? c]) {var result = '$a and $b';if (c != null) {result = '$result and $c';}return result;
}
  • 可选的命名参数
//设置[a]和[b]标志
void enableFlags({bool a, bool b}) {// ... 
}// 调用函数时,可以使用指定命名参数
enableFlags(bold: true, hidden: false)

7. mixin

Dart 是不支持多继承的,但是它支持 mixin。可以定义几个 mixin,然后通过 with 关键字将它们组合成不同的类(同名会被最后的覆盖)。如下例子:

class Person {say() {print('say');}
}mixin Eat {eat() {print('eat');}
}mixin Walk {walk() {print('walk');}
}mixin Code {code() {print('key');}
}class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}

8. 异步

Dart类库有非常多的返回Future或者Stream对象的函数,这些函数被称为异步函数。

8-1. Future

Future与JavaScript中的Promise非常相似。

// 使用Future.delayed 创建了一个延时任务,2秒后返回结果字符串,然后在then中接收异步结果并打印
Future.delayed(Duration(seconds: 2),(){return "hi world!";
}).then((data){// 执行成功print(data);
}).catchError((e){//执行失败会走到这里  print(e);
}).whenComplete((){//无论成功或失败都会走到这里
});
  • 多个异步:Future.wait
Future.wait([// 2秒后返回结果  Future.delayed(Duration(seconds: 2), () {return "hello";}),// 4秒后返回结果  Future.delayed(Duration(seconds: 4), () {return " world";})
]).then((results){print(results[0]+results[1]);
}).catchError((e){print(e);
});
  • 解决回调地狱:async/await
task() async {try{String id = await login("alice","******");String userInfo = await getUserInfo(id);await saveUserInfo(userInfo);// 执行接下来的操作} catch(e){// 错误处理print(e);}
}

8-2. Stream

Stream 也是用于接收异步事件数据,和 Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。 也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。 Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。

Stream.fromFutures([// 1秒后返回结果Future.delayed(Duration(seconds: 1), () {return "hello 1";}),// 抛出一个异常Future.delayed(Duration(seconds: 2),(){throw AssertionError("Error");}),// 3秒后返回结果Future.delayed(Duration(seconds: 3), () {return "hello 3";})
]).listen((data){print(data);
}, onError: (e){print(e.message);
},onDone: (){});// 上述代码依次输出
// hello 1
// Error
// hello 3

本次分享就到这儿啦,我是鹏多多,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~

往期文章

  • Vue2全家桶+Element搭建的PC端在线音乐网站
  • vue3+element-plus配置cdn
  • 助你上手Vue3全家桶之Vue3教程
  • 助你上手Vue3全家桶之VueX4教程
  • 助你上手Vue3全家桶之Vue-Router4教程
  • 超详细!Vue的九种通信方式
  • 超详细!Vuex手把手教程
  • 使用nvm管理node.js版本以及更换npm淘宝镜像源
  • vue中利用.env文件存储全局环境变量,以及配置vue启动和打包命令
  • 超详细!Vue-Router手把手教程

个人主页

  • CSDN
  • GitHub
  • 简书
  • 博客园
  • 掘金

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

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

相关文章

机器学习实验二:决策树模型

系列文章目录 机器学习实验一&#xff1a;线性回归机器学习实验二&#xff1a;决策树模型机器学习实验三&#xff1a;支持向量机模型机器学习实验四&#xff1a;贝叶斯分类器机器学习实验五&#xff1a;集成学习机器学习实验六&#xff1a;聚类 文章目录 系列文章目录一、实验…

linux管道_tee_xargs

5.2 管道 管道命令可以将多条命令组合起来&#xff0c;一次性完成复杂的处理任务。 语法&#xff1a; command1 | command2 | command3...例&#xff1a; 查看passwd中最后3行内容。 cat /etc/passwd | tail -3 查看passwd中包含root所在行的第一条信息。 cat /etc/p…

FPGA串口接收解帧、并逐帧发送有效数据——1

FPGA串口接收解帧、并逐帧发送有效数据 工程实现的功能&#xff1a;FPGA串口接收到串口调试助手发来的数据&#xff0c;将其数据解帧。判断到正确的帧头和帧尾之后&#xff0c;将有效数据存入rx_data中&#xff1b;另一方面发送端将有效数据逐帧发送出去。 参考&#xff1a;正…

【用Python根据用户名和手机号码生成Hash值并创建.cs .h和xlsx文件】

用Python根据用户名和手机号码生成Hash值并创建C Sharp .cs、嵌入式.h和xlsx表格文件 用Python根据用户名和手机号码生成Hash值并创建C Sharp .cs、嵌入式.h和xlsx表格文件&#xff0c;主要是为每个用户创建一个pubkey&#xff0c;并输出C Sharp C#和嵌入式 Keil的工程文件 pub…

字符编码演变

1.基础知识   我们在计算机屏幕上看到的是实体化的字符&#xff0c;而计算机存储介质中存放的实际上是二进制的比特流。这两者之间有一个转换规则&#xff0c;类比密码学中的加密解密&#xff0c;从“字符”到“比特流”称之为“编码”&#xff0c;从“比特流”到“字符”则称…

RAG落地实践、AI游戏开发、上海·深圳·广州线下工坊启动!星河社区重磅周

飞桨星河社区在成立的5年以来&#xff0c;已汇集660万AI开发者&#xff0c;覆盖深度学习初学者、在职开发者、企业开发者、高校教师、创业者等&#xff0c;已成为AI领域最具影响力的社区之一&#xff0c;无论是AI爱好者还是AI开发者&#xff0c;都能在这里探索AI的无限可能。飞…

城市分站建站系统源码 全新版本SEO推广优化排名高 附带完整的搭建教程

在过去的几年中&#xff0c;许多企业在建立网站时面临一些共同的问题&#xff1a;缺乏技术支持、不懂SEO、预算有限等。这些问题导致他们的网站无法充分发挥作用&#xff0c;无法在搜索引擎中获得良好的排名&#xff0c;进而影响到企业的业务发展。小编来给大家分享一款城市分站…

编译原理词法分析:NFA转DFA(原理+完整代码+可视化实现)

NFA转换为DFA 【本文内容摘要】 什么是DFA通过子集构造法将NFA转换为DFA生成DFA的dot文件并且形成可视化。 如果本文对各位看官有用的话&#xff0c;请记得给一个免费的赞哦&#xff08;收藏也不错&#xff09;&#xff01; 文章目录 NFA转换为DFA一、什么是DFA二、NFA转换为…

k8s引用环境变量

一 定义环境变量 ① 如何在k8s中定义环境变量 env、configmap、secret补充&#xff1a; k8s 创建Service自带的环境变量 ② 从pod属性中获取 kubectl explain deploy.spec.template.spec.containers.env.valueFrom关注&#xff1a; configMapKeyRef、fieldRef 和 resour…

初探Maven

文章目录 一、Maven概述二、安装配置Maven&#xff08;一&#xff09;下载Maven&#xff08;二&#xff09;安装Maven&#xff08;三&#xff09;配置Maven 三、IDEA里配置Maven&#xff08;一&#xff09;版本情况说明&#xff08;二&#xff09;配置构建工具Maven 一、Maven概…

如何批量修改ppt中的字体?

ppt制作已经属于是复杂的操作了&#xff0c;当我们想要更换ppt中的字体&#xff0c;有没有什么快捷的方法呢&#xff1f;今天分享两个方法&#xff0c;一键修改ppt文件字体。 方法一&#xff1a; 找到功能栏中的编辑选项卡&#xff0c;点击替换 – 替换字体&#xff0c;在里面…

python加速方法:纯CPU多进程加速(joblib库)

我写C 代码喜欢用OpenMP进行加速&#xff0c;在不更改源代码情况下只做稍稍修改即可实现CPU利用率最大化&#xff0c;跨平台移植也没有问题。 python是个好东西&#xff0c;苦恼于密级计算的时候只能使用单核&#xff0c;使用多线程不奏效&#xff0c;因为毕竟它受限于语言本身…

Javascript_根据截止日期超时自动返回

例如定时交卷功能&#xff0c;隐藏一个input id"endTime"存放超时时间&#xff0c;例如2023-12-01 20:56:15&#xff0c;使用如下代码即可实现超时自动处理。 <script src"/jquery.min.js"></script><script type"text/javascript&qu…

【Go】Go语言基础内容

变量声明&#xff1a; 变量声明&#xff1a;在Go中&#xff0c;变量必须先声明然后再使用。声明变量使用 var 关键字&#xff0c;后面跟着变量名和类型&#xff0c;如下所示&#xff1a; var age int这行代码声明了一个名为 age 的整数变量。 变量初始化&#xff1a;您可以在声…

二叉树遍历 LeetCode 1038. 从二叉搜索树到更大和树

1038. 从二叉搜索树到更大和树 给定一个二叉搜索树 root (BST)&#xff0c;请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。 从图中可以看出&#xff0c;每个节点是BST右中左遍历时&#xff0c;遍历到的节点的值加上之前所有节点的值。 在遍历时可以使…

全球与中国木质颗粒燃料市场:增长趋势、竞争格局与前景展望

木质颗粒汽油的主要优点之一是环境永续性。木质颗粒被认为是碳中立的&#xff0c;因为燃烧过程中释放的二氧化碳量大约等于木材生长过程中吸收的二氧化碳量。这种封闭的碳循环减少了温室气体净排放并减轻了气候变迁的影响。作为一种可再生资源&#xff0c;木屑颗粒还可以透过促…

Python必备神器揭秘:15个最热门库全解析

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python生态系统中拥有大量优秀的库&#xff0c;为开发者提供了广泛且强大的工具。本文将介绍15个最受欢迎的Python库&#xff0c;包括它们的功能、优点以及示例代码&#xff0c;帮助读者更全面地了解和使用这些库…

spring boot mybatis TypeHandler 源码如何初始化及调用

目录 概述使用TypeHandler使用方式在 select | update | insert 中加入 配置文件中指定 源码分析配置文件指定Mapper 执行query如何转换 结束 概述 阅读此文 可以达到 spring boot mybatis TypeHandler 源码如何初始化及如何调用的。 spring boot 版本为 2.7.17&#xff0c;my…

知识点滴 - 什么是AECS-PRM

AECS - PRM 是高级入境控制系统--旅客识别模块的缩写。该系统用于航空业&#xff0c;在登机过程中管理和核对乘客信息。AECS - PRM 有助于确保正确的乘客搭乘正确的航班&#xff0c;并加强安全措施。它可能涉及使用各种技术&#xff0c;如生物识别技术&#xff0c;以准确匹配乘…

深入理解Go语言GC机制

1、Go 1.3之前的标记-清除&#xff08;mark and sweep&#xff09;算法 Go 1.3之前的时候主要用的是普通的标记-清除算法&#xff0c;此算法主要由两个主要的步骤&#xff1a; 标记&#xff08;Mark phase&#xff09;清除&#xff08;Sweep phase&#xff09; 1&#xff09…