开发者社区> ws5ztcvob2aao> 正文

Flutter(三)——一篇文章掌握Dart语言的用法(三)

简介: Flutter(三)——一篇文章掌握Dart语言的用法(三)
+关注继续查看
福利推荐:阿里云、腾讯云、华为云等大品牌云产品全线2折优惠活动来袭,4核8G云服务器899元/3年,新老用户共享优惠,点击这里立即抢购>>>

异步编程


Dart语言和JavaScript语言的共同点是单线程,同步代码会阻塞程序,因此程序里能看到大量的异步操作,它是用Future对象来执行相关操作的,并且async函数使用await关键字时才被执行,直到一个Future操作完成,Future支持链式操作的方式,可以按顺序执行异步操作。


Future是什么?

一个Future是一个Future自身的泛型Flutter对象,它表示一个异步操作产生的T类型的结果,如果结果的值不可用,Future的类型会是Future,如果返回一个Future的函数被调用了,将会发生以下两件事:


(1)这个函数加入待完成的队列并且返回一个未完成的Future对象


(2)当这个操作结束了,Future对象返回一个值或者错误。


例如:


Future<int> future=getFuture();
future.then((value)=>handleValue(value))
    .catchError((error)=>handleError(error))
    .whenComplete()=>handlerComplete();


如果你是前端的开发人员,可以理解Future类似前端里的Promise。我们在future.then中接收异步处理结果,并根据业务需求做相应的处理。而future.catchError则用于在异步函数中捕获并处理错误。在有些业务场景下,无论是异步任务的处理结果是成功还是失败,我们都需要再进行一些处理,这时候可以使用Future的whenComplete进行回调。


async和await

当遇到需要延迟的运算(async)时,将其放到延迟运算的队列(await)中去,把不需要延迟的运算的部分先执行完,最后在来处理延迟的运算部分。但是,要使用await,就必须在有async标记的函数中运行,否则这个await会报错。


其实这个和JavaScript也很像,async和await是Future的语法糖(Syntacticsugar),解决了回调地狱(Callback Hell)的问题。


那么回调地狱又是什么?这个需要结合具体业务场景来说,比如“业务1->业务2->业务3”,这三个任务都是异步的,那么业务1成功之后调用业务1的then回调,然后业务1的then里面在调用业务2,依次类推,就形成了回调地狱。回调地狱多了之后,我们的代码会非常难看,因为需要大量的缩进,比如这种:

step1('step1').then(step1Result(){
    step2('step2').then(step2Result(){
  step3('step3').then(step3Result(){
    //依次类推456....
  })
    })
})


我们刚在上面讲解了async和await是Future的语法糖,我们在使用过程中给人的感觉是在调用同步的代码。为了解决这种回调地狱,我们对以上代码结构进行了一些调整,修改后的代码如下:

steps() async{
    try{
  String step1Result=await step1('step1');
  String step2Result=await step2(step1Result);
  String step3Result=await step3(step2Result);
  //456......
    }catch(e){
  print(e);
    }
}


从上面的代码我们可以看到,await必须被包裹在async里面,如果没有async就会报错。后续我们将通过其他章节在进行详细的使用。


继承,接口实现

在Dart语言中,继承和接口实现基本上与Java类似,但是我们需要注意以下几点:


(1)继承:构造函数不能被继承,而且在Dart语言中,没有Java中的公有与私有的修饰符,因此,可以直接访问超类中的所有变量与方法。


(2)接口实现:在Dart语言中,没有接口的修饰符,但是每个类都是一个隐式的接口,这个接口包含类里的所有成员变量与方法,当类被当作接口使用的时候,类中的方法就是接口中的方法,它需要在子类里重新被实现,而且实现的时候需要加上@override关键字。


使用方式如下:

abstract class A{
    void printA();
}
class B{
    void printB(){
    }
}
class C{
    void printC(){
  print('C');
    }
}
class SoftwareSngineer extends C implements A,B{
    @override
    void printA{
  //重写
    }
    @override
    void printB(){
  //重写
    }
}


混合

在Dart语言中,我们有一个新的特性,那就是混合的语言特性mixins,它的作用是在类中混入其他功能,mixins最早出现在Lisp语言中。你可以这么来理解,就是在面向对象的语言中,mixins是一个可以把自己的方法提供给其他类使用,但却不需要成为其他类的父类的类,它以非继承的方式来复用类中的代码。要使用mixins,则要用关键字with来复用类中的代码,使用方式如下:

abstract class A{
    factory A._(){
        return null;
    }
    void printA(){
        print('A');
    }
}
class C with A{
    @override
    void printA(){
        print('A');
    }
}
void main(){
    C()..printA();
}


那我们现在就有一个疑问了,如果同时使用继承,接口实现与混合,并且@override的方法都一样,那么执行的优先级会怎么样?我们直接上代码跑一下就清楚了:

class Cat{
    void show(){
        print('小猫');
    }
}
class Brid{
    void show(){
        print('小鸟');
    }
}
class Owner{
    void show(){
        print('主人');
    }
}
class person1 extends Owner with Cat,Brid{
    void show(){
        print('主人1养了猫和鸟');
    }
}
class person2 extends Owner with Cat implements Brid{
    void show(){
        print('主人2养了猫和鸟');
    }
}
void main(){
    person1()..show();
    person2()..show();
}


如果代码如上,没有任何注释,那么会直接执行类本身的方法,输出效果如下:

image


现在我们注释调用两个person中的方法,其他代码不变:


class person1 extends Owner with Cat,Brid{
    //void show(){
        //print('主人1养了猫和鸟');
    //}
}
class person2 extends Owner with Cat implements Brid{
    //void show(){
        //print('主人2养了猫和鸟');
    //}
}


那么现在打印出来的效果就是这样:


从这里我们可以看出来,假如使用了混合,继承与接口实现,那么它的执行优先级顺序是mixins->extends->implements。


泛型

在Dart语言中,泛型与Java中很相似,比如List。用尖括号括起来的就是泛型的写法。在List中,这个E代表泛型的类型,且不一定要用E表示,还可以用T,S,K等表示,我们先来简单的使用一下:

void main(){
    List animals=new List<String>();
    animals.addAll('小猫','小狗','小兔');
}


在上面代码中,我们使用了List集合来存储小动物,并且指定了List泛型,这样定义就说说明只能存储字符串类型。


Dart语言基础就这么多,重点都在后面,前面大部分只要学过其他的语言,看看根本不费劲,Dart语言是Flutter开发的主要语言,必须要掌握的哦。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Flutter如何调试应用【Dart Observatory 】以及调试模式断言
Flutter如何调试应用【Dart Observatory 】以及调试模式断言
112 0
Flutter(三)——一篇文章掌握Dart语言的用法(一)
Flutter(三)——一篇文章掌握Dart语言的用法(一)
102 0
Flutter(三)——一篇文章掌握Dart语言的用法(二)
Flutter(三)——一篇文章掌握Dart语言的用法(二)
88 0
[Flutter]足够入门的Dart语言系列之面向对象:类之间的6大关系
无论是面向对象编程,还是面向过程、函数式编程,代码与代码之间的组织关系都是最重要的。通过代码的编写、代码间的相互调用、不同代码的合理使用、集合不同的数据和方法,才能...
62 0
[Flutter]足够入门的Dart语言系列之面向对象:类成员的可见性、常量和工厂构造函数详解
类和成员的可见性,这在基于库或包的开发中非常重要,Dart中提供了工厂构造函数,可以方便的实现单例、缓存实例对象、返回子类等,以及常量构造函数的使用......
47 0
[Flutter]足够入门的Dart语言系列之面向对象:类的定义详解、成员和实例使用
类表示的是分类,一类问题或事物,它是对具体或现实世界的抽象。比如动物类、犬科动物类、猫科动物类、房子类、数学类,类是具体事物的描述,它不是指具体的某个动物、某栋房子、某个数学题,而是对它们的概括...
57 0
[Flutter]足够入门的Dart语言系列之函数:匿名函数、作用域闭包、类型别名和内联函数类型
函数在Dart中是对象,因此,可以将函数作为参数传递给另一个函数、作为一个'值'赋值给一个变量。下面主要介绍匿名函数、内联函数类型的使用,以及了解下作用域和闭包...
122 0
[Flutter]足够入门的Dart语言系列之函数:函数定义、调用、5种参数类型和main函数
函数(Function)也被称为方法(Method)。其最直观的理解就是数据中的函数,比如y=f(x),在编程中,f对输入x进行处理,返回结果y,就是一个函数......
130 0
[Flutter]足够入门的Dart语言系列之常见运算符或操作符
Dart中的运算符提供对数据操作和处理的能力,其中的算术运算符、逻辑运算符非常符合现实中的使用情况,其他不同的运算符则有着自己的操作逻辑...
85 0
[Flutter]足够入门的Dart语言系列之流程控制语句:中断和异常(continue/break、try...catch)
循环的执行是通过循环条件来控制的,但是,有时我们想要通过额外的条件判断,来决定是否中断执行,或者中断本次循环而继续执行下次及之后的循环;此外,我们需要对于异常情况的处理...
79 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Flutter企业级应用开发实战手册
立即下载
Flutter技术解析与实战
立即下载
Flutter in action
立即下载


http://www.vxiaotou.com