flutter 泛型_Flutter之旅:Dart语法扫尾-包访问-泛型--异常-异步-mixin

1、其他常用符号与关键字

1.1:级联操作符:..

那Paint对象的设置来看:

---->[情景1:曾经的写法]----

var paint = Paint();

paint.strokeCap = StrokeCap.round;

paint.style = PaintingStyle.stroke; //画线条

paint.color = Color(0xffBBC3C5); //画笔颜色

paint.isAntiAlias = true; //抗锯齿

paint.filterQuality = FilterQuality.high; //抗锯齿

---->[情景2:级联的写法]----

paint

..strokeCap = StrokeCap.round

..style = PaintingStyle.stroke //画线条

..color = Color(0xffBBC3C5) //画笔颜色

..isAntiAlias = true //抗锯齿

..filterQuality = FilterQuality.high;

很简洁,很高大上有木有,

1.2: 条件调用符:?.

---->[情景1:普通调用]----

void main() {

var a = -5;

print(a.abs());//5

}

---->[情景2:普通调用前置空,会崩掉]----

var a = 5;

a=null;

print(a.abs());//NoSuchMethodError: The method 'abs' was called on null.

---->[情景3:?.调用不会崩掉,只返回null]----

var a = 5;

a = null;

print(a?.abs()); //null

1.3:类型判断关键字、is 、 is!和as

var b=10;

print(b is String);//false

print(b is num);//true

print(b is! double);//true

String c="12315";

print((c as Comparable).compareTo("a"));//-1 强制类型转换

print((c as num).abs());//类型转换异常

// type 'String' is not a subtype of type 'num' in type cast

2.库的使用和可见性

2.1:库的基本使用

import 'dart:math';//导入math内置库

import 'package:flutter/material.dart';//根据文件系统路径到包

2.2:类库中的命名冲突: as 关键字的使用

当sin函数处于连个包中,并且两个包都被导入,该怎么办

---->[utils/color_utils.dart]----

sin(double d){

}

---->[main.dart:5]----

import 'package:toly/utils/color_utils.dart';

import 'dart:math';

void main() {

sin(5);

}

---->[解决方案]----

import 'package:toly/utils/color_utils.dart' as myMath;

import 'dart:math';

void main() {

myMath.sin(5);

}

2.3:控制显隐部分导入

被隐藏的对象无法被外界访问

import 'package:toly/utils/color_utils.dart' show sin;//只显示sin函数

import 'package:toly/utils/color_utils.dart' hide sin;//只隐藏sin函数

2.4:权限访问控制

需要注意的是,Dart中没有private,public,protected修饰符。 如何做到访问权限控制,是个问题,默认是可以被访问的。

---->[painter/person.dart]----

class Person{

String name;

int age;

Person(this.name,this.age);

say(){

print("my name is $name and i am $age years old.");

}

}

---->[main.dart]----

import 'package:toly/painter/person.dart';

void main() {

var toly = Person("toly", 25);

print(toly.age);//25

toly.say();//my name is toly and i am 25 years old.

}

Dart中规定,名称前加下划线可以限制外部的访问,如下_age。

方法名,文件名也是如此,不想对外暴露,前面加下划线即可

---->[painter/person.dart]----

class Person{

String name;

int _age;

Person(this.name,this._age);

say(){

print("my name is $name and i am $_age years old.");

}

}

---->[main.dart]----

void main() {

var toly = Person("toly", 25);

toly.say();//my name is toly and i am 25 years old.

print(toly._age);//报错

}

2.5:library和export关键字的使用

这里拿animation来举例子,使用时导包:import 'package:flutter/animation.dart';

在源码中animation.dart只做了一个归纳暴露的动作。

library animation;

export 'src/animation/animation.dart';

export 'src/animation/animation_controller.dart';

export 'src/animation/animations.dart';

export 'src/animation/curves.dart';

export 'src/animation/listener_helpers.dart';

export 'src/animation/tween.dart';

export 'src/animation/tween_sequence.dart';

3.泛型

Dart中的泛型和Java中非常相似,可以让类型变得安全,代码更加优雅。

3.1:泛型的使用

拿List类来说,在类定义时类名List后加了,在使用时List就可以加一个类型。这样的好处在于当你试图添加其他类型的数据到该List对象中时,会报错。这样就是的类型变得安全。

---->[sky_engine/lib/core/list.dart:54]----

abstract class List implements EfficientLengthIterable {

---->[main.dart]----

void main() {

var languages=List();//定义一个泛型为String的列表

var odd=List();//定义一个泛型为int的列表

}

3.2:List,Map,Set特殊的初始化

这并不算泛型特点,只是List,Map,Set快速初始化的写法。

只不过看起来有些奇怪,这里说一下,以后会常见这些写法。

var languageList = ['Java', 'Dart', 'Kotlin'];

var markMap = {'Java':100, 'Dart':80, 'Kotlin':60};

var languageSet = {'Java', 'Dart','Kotlin'};

3.3:泛型的限定

和Java语法一致,使用 来限定泛型的类型区域

如下面DiagnosticableNode中的泛型限定

class DiagnosticableNode extends DiagnosticsNode

3.4:泛型方法

在Dart中,方法也是可以支持泛型的,比如下面的方法:

当调用var e = foo("hello");则会报错,改为foo即可。

T add(T t) {

return t;

}

4.异步操作简介

关于异步,是一个挺大的话题,这里简单提一下,之后有详细介绍。

4.1:异步在Dart中的必要性

Dart是一个单线程的编程语言,耗时操作会造成线程阻塞。

就相当于我在烧开水,水烧开之前都无法进行其他动作,这显然是不合理的。

我完全可以在烧水的时候去扫地,等水开了再去处理,需要一个Future对象用于后续处理

class Water{

double temperature;

Water(this.temperature);

Future heat() {

temperature=100;

return Future (()=>this);

}

}

main(){

print("打开烧水开关");

Water(0).heat().then((water){

print('水已经烧开,现在温度:${water.temperature},开始冲水');

});

print("扫地");

}

4.2:async和await关键字的使用

async表示异步,await表示等待。注意在异步操作中返回的是Future对象

这个对象用于,后续的处理,比如水烧开后去冲水什么的。

heat() async{

var water = await Water(0).heat();

print('水已经烧开,现在温度:${water.temperature},开始冲水');

return water;

}

可以卡看出,打开烧水开关后,接着是扫地,水烧开后再冲水,这就是异步操作。

更多的用法将在后面文件资源的读取时做详细阐述。

5.异常处理

5.1:异常不处理的情况

结果由于FormatException异常,程序直接崩溃

这并不是我们想要的,直接崩溃会造成极差的用户体验。

void main() {

print(str2Num("a"));//FormatException: a

}

num str2Num(String str){

return num.parse(str);

}

5.2:异常捕捉

这个和Java也是类似的,使用try…catch…finally代码块

这样异常会通过日志打印并且程序不会崩溃退出。 其中finally代码块中的语句不管异常与否,都会被执行

num str2Num(String str){

var result= 0;

try {

result= num.parse(str);

} catch (e) {

print('发生异常:$e');

} finally {

print('最终会被执行的代码块');

}

return result;

}

5.3:指定异常或多个异常捕捉

使用on关键字,可以指定捕捉某一类异常。

num str2Num(String str){

var result= 0;

try {

result= num.parse(str);

} on FormatException catch (e) {

print('发生Format异常:$e');

} on IOException catch(e){

print('发生IO异常:$e');

} finally {

print('最终会被执行的代码块');

}

return result;

}

6.Dart中的多继承

知道Dart支持多继承,我是挺惊讶的,多继承的问题在于父类构造可能被循环调用

6.mixin的使用

6.1:子类和父类构造函数调用顺序

通过下面的代码可以看出,是先调用父类的构造方法

class Living {

Living(){

print("Runner");

}

}

class Person extends Living{

Person(){

print("Person");

}

}

main(){

Person toly = Person();

}

---->[打印结果]----

Runner

Person

6.2:mixin是什么?

首先mixin是一个定义类的关键字。直译出来是混入,混合的意思

Dart为了支持多重继承,引入了mixin关键字,它最大的特殊处在于:

mixin定义的类不能有构造方法,这样可以避免继承多个类而产生的父类构造方法冲突

class Living {

Living(){

print("Runner");

}

}

class Runner {

run(){

print("run");

}

}

class Walker{

walk(){

print("run");

}

}

class Person extends Living with Walker,Runner{

Person(){

print("Person");

}

}

main(){

Person toly = Person();

toly.run();

toly.walk();

}

使用方法很简单,在with关键字后面将类名,这是该类就是mixin类

mixin就相当于将其他类的能力混入到当前类,还是挺厉害的。

唯一的限制就是mixin类无法拥有构造函数,如果有构造方法会怎样? 报错呗。

6.3:关于mixin关键字

使用class关键字定义的类是可以当做mixin类使用的,比如上面的。

另外使用mixin关键字也可以来定义mixin类,如:

mixin Walker{

walk(){

print("run");

}

}

唯一的区别在于,你是否确定它是一个mixin类。

当你在mixin声明的类中定义构造方法,会直接报错。

6.4:关于混入的方法重名

取后混入的

class Runner {

go(){

print("Runner-go");

}

}

mixin Walker{

go(){

print("Walker-go");

}

}

class Person with Runner,Walker{

Person(){

print("Person");

}

}

main(){

Person toly = Person();

toly.go();//Walker-go

}

你可能感兴趣的:(flutter,泛型)