找回密码
 立即注册
首页 业界区 安全 flutter学习-day3-dart基础

flutter学习-day3-dart基础

焦和玉 2025-6-1 21:44:40
目录

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

    • 8-1. Future
    • 8-2. Stream


本文学习和引用自《Flutter实战·第二版》:作者:杜文
1. 变量声明


  • var
类似于 JavaScript 中的var,它可以接收任何类型的变量,但最大的不同是 Dart 中 var 变量一旦赋值,类型便会确定,则不能再改变其类型:
  1. var name = "李四"
  2. /// 对
  3. name = "张三"
  4. /// 错
  5. name = 1000
复制代码

  • Object
Object 是 Dart 所有对象的根基类,也就是说在 Dart 中所有类型都是Object的子类(包括Function和Null),所以任何类型的数据都可以赋值给Object声明的对象,且后期可以改变赋值的类型。但是声明的对象只能使用 Object 的属性与方法, 否则编译器会报错。
  1. Object t = 1000
  2. t = "张三"
  3. print(t.length) // 错
复制代码

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

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

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

  • 空安全
Dart 中一切都是对象,这意味着如果我们定义一个数字,在初始化它之前如果我们使用了它,假如没有某种检查机制,则不会报错。如下:
  1. test() {
  2.   int i;
  3.   print(i*8); // 错
  4. }
复制代码
在 Dart 引入空安全之后,如果一个变量没有初始化,则不能使用它,否则编译器会报错:
  1. int a = 10
复制代码
声明时候可以加上?,指定变量是可空:
  1. String? name;
复制代码
如果我们预期变量不能为空,但在定义时不能确定其初始值,则可以加上late关键字,表示会稍后初始化,但是在正式使用它之前必须得保证初始化过了,否则会报错:
  1. late int c;
  2. c = 100
复制代码
如果一个变量我们定义为可空类型,且判空了,但是预处理器仍然有可能识别不出,这时我们就要在变量后面加一个!符号,告诉预处理器它已经不是null了。
  1. class Test() {
  2.   int? d;
  3.   log() {
  4.     if (d! = null) {
  5.       print(d! * 100)
  6.     }
  7.   }
  8. }
复制代码
如果函数变量可空时,调用的时候可以用语法糖:
  1. fun?.call()
复制代码

  • 特殊声明模式
  1. // 同时声明
  2. var (a, [b, c]) = ('str', [1, 2])
  3. // 同时声明
  4. var (c, d) = ('left', 'right');
  5. // 交换2个值
  6. (c, d)  = (d, c)
  7. // 解构
  8. var (name, age) = userInfo(json)
  9. // 省略符
  10. var (a, b, ...rest) = [1, 2, 3, 4, 5, 6] // 1 2 [3,4,5,6]
  11. var (a, b, ...rest, c, d) = [1, 2, 3, 4, 5, 6] // 1 2 [3,4] 5 6
  12. var (a, b, ..., c, d) = [1, 2, 3, 4, 5, 6] // 1 2 5 6
复制代码
2. 操作符


  • 算数运算符
符号意义描述+加--减-*乘-/除-~/除返回整数结果%取余获取整数除法的余数

  • 等于运算符
符号意义描述==平等-!=不相等->大于-</tdtd小于/tdtd-/td/trtrtd>=大于或等于->>=右移赋值(无符号右移)-

  • 类型运算符
符号意义描述as类型转换断言-is如果对象具有指定的类型,则为 True-is!如果对象没有指定的类型,则为 True-
  1. // 如果您不确定该对象的类型是否为Person,则在使用对象之前用is检查
  2. if (employee is Person) {
  3.   employee.firstName = 'Bob';
  4. }
复制代码

  • 按位运算符
符号意义描述&与-|或-^异或-</tdtd左移/tdtd-/td/trtrtd>右移->>>无符号右移-

  • 条件表达式
语法意义描述condition ? expr1 : expr2赋值三元表达式expr1 ?? expr2赋值如果 expr1 为非 null,则返回其值; 否则,计算并返回 expr2 的值?.xxx短路条件成员访问!断言将表达式强制转换为其基础不可为 null 的类型

  • 级联表示法
级联允许您在同一对象上,进行一系列操作。
  1. // 级联语法
  2. var paint = Paint()
  3.   ..color = Colors.black
  4.   ..strokeCap = StrokeCap.round
  5.   ..strokeWidth = 5.0;
  6. // 等价于如下语法
  7. var paint = Paint();
  8. paint.color = Colors.black;
  9. paint.strokeCap = StrokeCap.round;
  10. paint.strokeWidth = 5.0;
复制代码
  1. // 级联语法
  2. querySelector('#confirm')
  3.   ?..text = 'Confirm'
  4.   ..classes.add('important')
  5.   ..onClick.listen((e) => window.alert('Confirmed!'))
  6.   ..scrollIntoView();
  7. // 等价于如下语法
  8. var button = querySelector('#confirm');
  9. button?.text = 'Confirm';
  10. button?.classes.add('important');
  11. button?.onClick.listen((e) => window.alert('Confirmed!'));
  12. button?.scrollIntoView();
复制代码
3. 数据类型

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


  • switch
  1. int size = 2;
  2. // 条件判断
  3. switch (size) {
  4.   case 1:
  5.     print('一');
  6.   case [2, 3]:
  7.     print('二 and 三')
  8.   case [4 || 5]:
  9.     print('四 or 五')
  10.   case >= 6 && <= 10
  11.     print('六 to 十')
  12. }
  13. // 条件赋值
  14. var bg = Color.green
  15. var isPrimary = switch (bg) {
  16.   Color.red || Color.yellow || Color.blue => true,
  17.   _ => false
  18. }
复制代码

  • for
  1. var message = StringBuffer('Dart is fun');
  2. for (var i = 0; i < 5; i++) {
  3.   message.write('!');
  4. }
复制代码

  • fon-in
  1. Map<String, int> listMap = {
  2.   'a': 23,
  3.   'b': 100,
  4. };
  5. for (final MapEntry(key: key, value: value) in listMap.entries) {
  6.   print('键:$key 值:$value');
  7. }
复制代码

  • while
  1. while (!isDone()) {
  2.   doSomething();
  3. }
复制代码

  • do-while
  1. do {
  2.   printLine();
  3. } while (!atEndOfPage());
复制代码

  • 跳过和停止
  1. while (true) {
  2.   if (shutDownRequested()) break;
  3.   processIncomingRequests();
  4. }
  5. for (int i = 0; i < candidates.length; i++) {
  6.   var candidate = candidates[i];
  7.   if (candidate.yearsExperience < 5) {
  8.     continue;
  9.   }
  10.   candidate.interview();
  11. }
复制代码

  • if
  1. if (isRaining()) {
  2.   you.bringRainCoat();
  3. } else if (isSnowing()) {
  4.   you.wearJacket();
  5. } else {
  6.   car.putTopDown();
  7. }
复制代码

  • if-case
  1. // 接受一个名为pair的参数。如果pair的类型是[int x, int y],则返回一个Point(x, y)对象
  2. if (pair case [int x, int y]) return Point(x, y);
复制代码
5. 错误处理和捕获

异常捕获和JavaScript差不多
  1. try {
  2.   breedMoreLlamas();
  3. } on OutOfLlamasException {
  4.   // 特定的异常
  5.   buyMoreLlamas();
  6. } on Exception catch (e) {
  7.   // 任何其他的例外
  8.   print('Unknown exception: $e');
  9. } catch (e) {
  10.   // 没有指定类型,处理所有类型
  11.   print('Something really unknown: $e');
  12. } finally {
  13.   cleanLlamaStalls();
  14. }
复制代码

  • 若要部分处理异常, 同时允许它传播, 使用关键字:rethrow
  1. void misbehave() {
  2.   try {
  3.     dynamic foo = true;
  4.     print(foo++); // 运行时错误
  5.   } catch (e) {
  6.     print('misbehave() partially handled ${e.runtimeType}.');
  7.     rethrow; // 允许调用者看到异常
  8.   }
  9. }
  10. void main() {
  11.   try {
  12.     misbehave();
  13.   } catch (e) {
  14.     print('main() finished handling ${e.runtimeType}.');
  15.   }
  16. }
复制代码

  • 断言
在开发过程中,使用断言语句,如果布尔条件为false,则触发。如果条件为true,则不触发。在生产代码中,断言将被忽略。
  1. // assert(条件, 可选消息)
  2. var sizi = 101;
  3. assert(size < 100, "Error:size 小于 100!");
复制代码
6. 函数

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

  • 函数声明
  1. bool isNoble(int ) {
  2.   return atomicNumber > 40;
  3. }
  4. bool isNoble (int atomicNumber) => atomicNumber > 40;
复制代码

  • 函数作为参数传递
  1. //定义函数execute,它的参数类型为函数
  2. void execute(var callback) {
  3.   // 执行传入的函数
  4.   callback();
  5. }
  6. // 调用execute,将箭头函数作为参数传递
  7. execute(() => print("xxx"))
复制代码

  • 可选的位置参数
  1. String say(String a, String b, [String? c]) {
  2.   var result = '$a and $b';
  3.   if (c != null) {
  4.     result = '$result and $c';
  5.   }
  6.   return result;
  7. }
复制代码

  • 可选的命名参数
  1. //设置[a]和[b]标志
  2. void enableFlags({bool a, bool b}) {
  3.   // ...
  4. }
  5. // 调用函数时,可以使用指定命名参数
  6. enableFlags(bold: true, hidden: false)
复制代码
7. mixin

Dart 是不支持多继承的,但是它支持 mixin。可以定义几个 mixin,然后通过 with 关键字将它们组合成不同的类(同名会被最后的覆盖)。如下例子:
  1. class Person {
  2.   say() {
  3.     print('say');
  4.   }
  5. }
  6. mixin Eat {
  7.   eat() {
  8.     print('eat');
  9.   }
  10. }
  11. mixin Walk {
  12.   walk() {
  13.     print('walk');
  14.   }
  15. }
  16. mixin Code {
  17.   code() {
  18.     print('key');
  19.   }
  20. }
  21. class Dog with Eat, Walk{}
  22. class Man extends Person with Eat, Walk, Code{}
复制代码
8. 异步

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

Future与JavaScript中的Promise非常相似。
  1. // 使用Future.delayed 创建了一个延时任务,2秒后返回结果字符串,然后在then中接收异步结果并打印
  2. Future.delayed(Duration(seconds: 2),(){
  3.   return "hi world!";
  4. }).then((data){
  5.   // 执行成功
  6.   print(data);
  7. }).catchError((e){
  8.    //执行失败会走到这里  
  9.    print(e);
  10. }).whenComplete((){
  11.    //无论成功或失败都会走到这里
  12. });
复制代码

  • 多个异步:Future.wait
  1. Future.wait([
  2.   // 2秒后返回结果  
  3.   Future.delayed(Duration(seconds: 2), () {
  4.     return "hello";
  5.   }),
  6.   // 4秒后返回结果  
  7.   Future.delayed(Duration(seconds: 4), () {
  8.     return " world";
  9.   })
  10. ]).then((results){
  11.   print(results[0]+results[1]);
  12. }).catchError((e){
  13.   print(e);
  14. });
复制代码

  • 解决回调地狱:async/await
  1. task() async {
  2.   try{
  3.     String id = await login("alice","******");
  4.     String userInfo = await getUserInfo(id);
  5.     await saveUserInfo(userInfo);
  6.     // 执行接下来的操作
  7.   } catch(e){
  8.     // 错误处理
  9.     print(e);
  10.   }
  11. }
复制代码
8-2. Stream

Stream 也是用于接收异步事件数据,和 Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。 也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。 Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。
  1. Stream.fromFutures([
  2.   // 1秒后返回结果
  3.   Future.delayed(Duration(seconds: 1), () {
  4.     return "hello 1";
  5.   }),
  6.   // 抛出一个异常
  7.   Future.delayed(Duration(seconds: 2),(){
  8.     throw AssertionError("Error");
  9.   }),
  10.   // 3秒后返回结果
  11.   Future.delayed(Duration(seconds: 3), () {
  12.     return "hello 3";
  13.   })
  14. ]).listen((data){
  15.   print(data);
  16. }, onError: (e){
  17.   print(e.message);
  18. },onDone: (){});
  19. // 上述代码依次输出
  20. // hello 1
  21. // Error
  22. // hello 3
复制代码
本次分享就到这儿啦,我是鹏多多,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~
PS:在本页按F12,在console中输入document.querySelectorAll('.diggit')[0].click(),有惊喜哦
公众号
1.jpeg

往期文章

  • flutter学习-day1-环境搭建和启动第一个项目
  • Vue2全家桶+Element搭建的PC端在线音乐网站
  • 超详细的Cookie增删改查
  • 助你上手Vue3全家桶之Vue-Router4教程
  • 助你上手Vue3全家桶之Vue3教程
  • 助你上手Vue3全家桶之VueX4教程
  • 使用nvm管理node.js版本以及更换npm淘宝镜像源
  • 超详细!Vue-Router手把手教程
  • 超详细!Vue的九种通信方式
  • 超详细!Vuex手把手教程
个人主页

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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册