Flutter——Dart详解

变量

变量的声明

var——没有初始值,可以变成任何类型。有初始值,类型被锁定
var data=123;
data='123';//不可,编译器直接报错
dynamic——动态任意类型,编译时不会检查
dynamic data2=123;
data2='123';//不会报错
object——动态任意类型,编译时会检查
object data2=123;
data2='123';//不会报错

变量默认值

一切皆对象,默认值都为null
没有初始化的变量默认为null

final和const

声明的类型可以省略
final (String 省略) str='123'
const (String 省略) str='123'
初始化后不能再赋值
不能和var同时使用
类级别常量,使用static const
const可以用其它const常量来初始化值
const a=1;
const b=2;
const sum=a*b;
使用const赋值声明,const可以省略
const list=const [];
const list=[];//也可
可以改非final、非const变量值,即使曾经是const值
var list1= const [1,2,3];
const list2= const [1,2,3];
fial list3= const [1,2,3];

list1=[1];
list2=[2];//编译器直接报错
list3=[3];//编译器直接报错
const导致的不可变性,是可以传递的
final List ls=[1,2,3];
ls[1]=0;//正确可以修改

const List ls=[1,2,3];
ls[1]=0;//编译后报错,不可以修改
const的不可变性传递给了它的子元素
相同的const常量不会在内存中重复创建
final List ls=[1,2,3];
final List ls2=[1,2,3];
//打印后不相等两内存不同

const List ls=[1,2,3];
const List ls2=[1,2,3];
//打印后不相等两内存相同
const需要是编译时常量
final fl=DateTIme.now();

const fl=DateTIme.now();//编译后报错

//DateTime.now是运行时才能确定的常量,但const要求的是编译前就能确定

内置类型

Numbers
int:整数值
double:64bit双精度浮点
int和double是num的子类
Strings

可以用单引号或双引号创建字符串

String a="111" "222" "333";//拼接也可以这么写,不会出错
String b='''abc
            def
            ghi
        ''';

打印后输出
            abc
            def
            ghi

可以用三个单引号或双引号创建多行的字符串

String b='''abc\ndef
        ghi
    ''';
打印后输出
        abc
        def
        ghi

r表示raw字符串

String b=r'''abc\ndef
            ghi
        ''';
打印后输出
            abc\ndef
            ghi

级联符

StringBuffer sb=StringBuffer();
sb.write('abc');
sb.write('def');
sb.write('ghi');

可以写成
sb..write('abc')..write('def')..write('ghi')..writeAll(['a','b','c']);
..表示集连符,链式调用
Booleans
bool对象未初始化则是null
Lists
Dart中可以直接打印list包括list的元素
支持泛型
有增删改查,支持倒序,自带排序,洗牌,可以使用+将两个list合并
Sets

set1.difference;

set1.difference(set2);返回set1集合里面有但是set2里面没有的
    Set set1=Set();
    Set set2=Set();
    set1.addAll([1,2,3,4]);
    set2.addAll([1,2,5,6]);
    var difference=set1.difference(set2);
    print(difference);
    打印输出
        {3,4}

set1.intersection

set1.intersection(set2);返回set1和set2的交集

set1.union(set2)

set1.union(set2);返回set1和set2的并集

set1.retainAll

set1.retainAll();把只保留某些元素(要保留的元素在原set中存在)。把set1变成了交集

Set set1 = Set();
set1.addAll([1,2,3]);
Set set2 = Set();
set2.addAll([1,5,6]);

set1.retainAll(set2);

打印set1得到
            {1}

intersection和retainAll的区别:
intersection返回交集
retainAll把set1变成交集
Maps
Runes–符号字符
    Runes runes = new Runes('\u6211');
    var str1 = String.fromCharCodes(runes);  
    print(str1);

    打印得到
            我
Symbols–标识符
有关反射,已被移除了

函数

定义

可以在函数内定义
定义函数可以省略类型,所有函数都有一个返回值,没有指定,则返回值则默认 return null;
int add(int a,int b){
    return a+b;
}
对于只有一个表达式的方法,可以用=>表达式来定义
int add(int a,int b) => a+b;

可选参数

可选命名参数。使用 {param1, param2, …} 的形式来指定命名参数。
int add({int a,int b}) => a+b;
print(add());
print(add(a:1));
print(add(b:1));
print(add(a:1,b:1));
可选位置参数
int add2(int a, [int b, int c]) => a+b;

print(add2(1));
print(add2(1,2));
print(add2(1,2,2));//输出3

以上有些会报错是因为a或b为null了
int+null不能转为int,会报错

默认值
可选位置默认值。曾经有用:的,现在建议用等号
int add2(int a , [int b=2, int c=2]) => a+b;

int add2(int a , {int b=2, int c=2}) => a+b;

可使用list或map作为默认值,但必须是const。
int add2({List list=const[1,23]}) {
}

匿名函数

无参匿名
var a=()=>print('123');
有参匿名
var a=(name)=>print('${name}');
可在其他函数中直接调用或传递给其他函数
List test(List list, String func(str)) {
    for (var i = 0; i < list.length; i++) {
        list[i] = func(list[i]);
    }
    return list;
}

var ls = ['aaa', 'bbb', 'vvv'];
print(test(ls, (str) => str * 2));

打印得
    ['aaaaaa','bbbbbb','vvvvvv'];

闭包

Function makeAddFunc(int x) {
    x++;
    return (int y) => x + y;
}

var addFun2 = makeAddFunc(2);
var addFun4 = makeAddFunc(4);
print(addFun2(2));//输出5
print(addFun4(3));//输出8

函数别名

typedef不能写在函数里面

typedef MyFunc(int a, int b);

void main() {
add(int a, int b) {
    print('${a+b}');
}

divide(int a, int b) {
    print('${a/b}');
}

MyFunc myFunc=add(1, 2);//得到3
myFunc=divide(20, 5);//得到4.0

 calcuter(int a, int b, MyFunc func) {
    func(a, b);
}

calcuter(8, 10, add);//得到18

操作符

后缀操作
String s;
print(s?.length);
print(s != null ? s.length : '');//Java中判空写法
前缀操作
print(1 / 2);//输出0.5
print(4 / 2);//输出2.0
print(1 ~/ 2);//输出0 先1/2,然后去掉小数点
print(4 / 2);//输出2
类型操作
num n = 1;
num n1 = 1.0;
//as 类型转换
int i = n as int;

print(i);
//is判断类型
print(n is double);

print(n is! double);
判断是否为空
java中:表达式?条件1:条件2;表达式true返回条件1,false返回条件2;
dart中:条件1??条件2;??左边非空则返回左边结果,否则返回右边
级联
..
赋值
??=左边为null,则右边赋值给左边,否则保持不变
bool gg=true;
gg??=false;
print(gg);//输出true
运算符重载

重载+
重载-

class Parent {
    final int x;
    final int y;

    const Parent(this.x, this.y);

    //重载+
    Parent operator +(Parent w) {
        return Parent(x + w.x, y + w.y);
    }
    
    //重载-
    Parent operator -(Parent w) {
        return Parent(x - w.x, y - w.y);
    }
}

void main() {
    final w1 = Parent(2, 3);
    final w2 = Parent(3, 4);
    final sum1 = w1 + w2;
    final sum2 = w1 - w2;
    print([sum1.x, sum1.y]);
    print([sum2.x, sum2.y]);
}

异常

Exception类型
Error类型
抛出
//抛出Exception对象
throw new FormatException('格式化异常');
//抛出Error对象
throw new OutOfMemoryError();
//抛出任意非null对象
throw '这是一个异常'
捕获
使用 on 来指定异常类型,使用 catch 来 捕获异常对象。
try {
    throw new OutOfMemoryError();
} on OutOfMemoryError {
    print('没有内存了');
} on Error catch(e) {//指定对象类型
    print('Unknown error: $e');
} catch (e, s) {
    print('Exception details: $e');//异常对象
    print('Stack Trace: $s');//堆栈信息
} finally {
    print('end');
} 

构造函数
命名构造函数
重定向构造函数
Java中
    class Point {
        num x;
        num y;

        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

Dart中
    class Point {
        num x;
        num y;

        //构造函数
        Point(this.x, this.y);

        //命名构造函数,相当于是取了别名
        Point.fromJson(Map json) {
            x = json['x'];
            y = json['y'];
        }

        //重定向构造函数,使用冒号调用其他构造函数
        Point.alongXAxis(num x) : this(x, 0);
    }
初始化列表
import 'dart:math';

class Point {
//final变量不能被修改,必须被构造函数初始化
final num x;
final num y;
final num distanceFromOrigin;

//初始化列表
Point(x, y)
    : x = x,
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y);
}
超类构造函数
class Parent {
    int x;
    int y;

    //父类命名构造函数不会传递  
    Parent.fromJson(x, y)
        : x = x,
            y = y {
        print('父类命名构造函数');
    }

}

class Child extends Parent {
    int x;
    int y;

    //重定向
    //若超类没有默认构造函数, 需要手动调用超类其他构造函数
    Child(x, y) : super.fromJson(x, y) {
        //调用父类构造函数的参数无法访问 this
        print('子类构造函数');
    }

    //在构造函数的初始化列表中使用super(),需要把它放到最后
    Child.fromJson(x, y)
        : x = x,
            y = y,
            super.fromJson(x, y) {
        print('子类命名构造函数');
    }
}
常量构造函数
class Point {
    //定义const构造函数必须保证变量都是final
    final num x;
    final num y;

    const Point(this.x, this.y);
}
工厂构造函数
class Singleton {
    String name;

    //工厂构造函数无法访问this,所以这里用static
    static Singleton _singleton;

    //工厂函数不会自动生成实例
    factory Singleton([String name = 'singleton']) {
        return Singleton._singleton ??= Singleton._newObject(name);
    }

    //匿名构造函数,省略方法体
    //  Singleton._newObject(name){
    //    this.name=name
    //  }
    Singleton._newObject(this.name);
}
setter和getter
class Recttangle {
    num top;
    num left;
    num width;
    num height;

    Recttangle(this.top, this.left, this.height, this.width);

    // num get right => left + width;
    num get right {
        return left + width;
    }

    //set right(num value) => left = value - width
    set right(value) {
        left = value - width;
    }

    num get bottom {
        return top + height;
    }

    set bottom(value) {
        top = value - height;
    }
}
抽象类

abstract修饰class
不能被是实例化,除非定义一个工厂构造函数

工厂模式
abstract class Foods {
//工厂模式
factory Foods(String type) {
    if (type == 'friuts') {
    return FriutsMessage();
    } else if (type == 'vegetables') {
    return VegetablesMessage();
    } else {
    return SnacksMessage();
    }
}

void doEat();
}

class FriutsMessage implements Foods {
    @override
    void doEat() {
        print('水果');
    }
}

class VegetablesMessage implements Foods {
    @override
    void doEat() {
        print('蔬菜');
    }
}

class SnacksMessage implements Foods {
    @override
    void doEat() {
        print('零食');
    }
}

void main() {
    FriutsMessage friutsMessage = FriutsMessage();
    friutsMessage.doEat();
    VegetablesMessage vegetablesMessage = VegetablesMessage();
    vegetablesMessage.doEat();
    SnacksMessage snacksMessage = SnacksMessage();
    snacksMessage.doEat();
}
顶级函数
//顶级函数
Foods foodsFactory(String type) {
    if (type == 'friuts') {
        return FriutsMessage();
    } else if (type == 'vegetables') {
        return VegetablesMessage();
    } else {
        return SnacksMessage();
    }
}

class FriutsMessage extends Foods {
    @override
    void doEat() {
        print('水果');
    }
}

class VegetablesMessage extends Foods {
    @override
    void doEat() {
        print('蔬菜');
    }
}

class SnacksMessage extends Foods {
    @override
    void doEat() {
        print('零食');
    }
}

void main() {
    FriutsMessage friutsMessage = FriutsMessage();
    friutsMessage.doEat();
    VegetablesMessage vegetablesMessage = VegetablesMessage();
    vegetablesMessage.doEat();
    SnacksMessage snacksMessage = SnacksMessage();
    snacksMessage.doEat();
}
可调用类
class ClassFunction {
    call(String a, String b, String c) => '$a $b $c!';
}

main() {
    var cf = new ClassFunction();
    var out = cf("dongnao","flutter","damon");
}
实现call方法可以让类像函数一样被调用

Mixin

abstract class Transportation {
    void transport();
}

class Bicycle extends Transportation {
    String safeIndex() => 'low';

    String powerUnit() => '两个轮子';

    String engery() => '脚蹬';

    @override
    void transport() {
            print('${safeIndex()}+${powerUnit()}+${engery()}');
    }
}

class Moto extends Transportation {
    String safeIndex() => 'low';

    String powerUnit() => '两个轮子';

    String engery() => '汽油';

    @override
    void transport() {
        print('${safeIndex()}+${powerUnit()}+${engery()}');
    }
}

class Car extends Transportation {
    String safeIndex() => 'middle';

    String powerUnit() => '四个轮子';

    String engery() => '汽油';

    @override
    void transport() {
        print('${safeIndex()}+${powerUnit()}+${engery()}');
    }
}

使用Mixin机制

abstract class Transportation {
    void transport();
}

abstract class TwoWheel {
    String powerUnit() => '两个轮子';
}

abstract class FourWheel {
    String powerUnit() => '四个轮子';
}

abstract class LowSafe {
    String safeIndex() => 'low';
}

abstract class MiddleSafe {
    String safeIndex() => 'middle';
}

abstract class BodyEnergy {
    String engery() => '脚蹬';
}

abstract class GasEnergy {
    String engery() => '汽油';
}

class Bicycle extends Transportation with TwoWheel, LowSafe, BodyEnergy {
    @override
    void transport() {
        print('${safeIndex()}+${powerUnit()}+${engery()}');
    }
}

class Moto extends Transportation with TwoWheel, LowSafe, GasEnergy {
    @override
    void transport() {
        print('${safeIndex()}+${powerUnit()}+${engery()}');
    }
}

class Car extends Transportation with FourWheel, MiddleSafe, GasEnergy {
    @override
    void transport() {
        print('${safeIndex()}+${powerUnit()}+${engery()}');
    }
}

Minx机制中顺序

class A {
    String getMessage() => 'A';
}

class B {
    String getMessage() => 'B';
}

class P {
    String getMessage() => 'P';
}

class AB extends P with A, B {}

class BA extends P with B, A {}

class ABO extends P with B implements A{
    String getMessage() => '本身';
}

class ABI extends P with B implements A{}

void main() {
    print(AB().getMessage()); //输出B
    print(BA().getMessage()); //输出A
    print(ABO().getMessage()); //输出本身
    print(ABI().getMessage()); //输出B
}

小结
本方法>with最后一个>with其它>implement

泛型

Java中的泛型信息是编译时的,泛型信息在运行时是不存在的
Dart的泛型类型是固化的,在运行时也有可以判断的具体类型

使用核心库
import 'dart:Math'

void main(){
    print(sqrt(8));
}
使用第三方库
pubspec.yaml

dependencies:
flutter:
    sdk: flutter

cupertino_icons: ^0.1.0
dio: ^2.1.0

XX.dart中
import "package:dio/dio.dart";
导入文件
import 'mylib.dart';
导入文件冲突
import 'MyLib1.dart' as lib1; 
import 'MyLib2.dart' as lib2; 

void main() {
    var myLib = lib1.MyLib();
    var myLib2 = lib2.MyLib();
}
选择性载入
import 'Mylib1.dart' as lib1 show Test;
import 'Mylib2.dart' as lib2 hide Test;

var test = lib1.Test();
var lib = lib2.MyLib();
延迟载入
import 'MyLib1.dart' deferred as lazyLib;

void main() {
    lazyLoad();
}
lazyLoad() async {
    await lazyLib.loadLibrary();
    var t = lazyLib.Test();
    t.test();
}
自定义库

mylib/tool.dart

part of mylib;
void printTool() => print('tool');

mylib/util.dart

part of mylib;
void printUtil() => print('util');

mylib/mylib.dart

library mylib;

part 'util.dart';
part 'tool.dart';

void printMyLib() => print('mylib');

main.dart

import 'mylib/mylib.dart';

void main() {
    printMyLib();
    printUtil();
    printTool();
}

异步

####async和await

返回的Future对象
如果需要监听“完毕”这个状态,那么用whenComplete,需要监听“成功”这个状态,用then,需要监听“失败”这个状态,用catchError。

import 'dart:async';

void main() {
    getName();
}

Future<void> getName() async {
    await getStr(); //等getStr做完
    print('name');
}

getStr() {
    print('getStr');
}

打印输出 getStr
        name


void main() {
    getName();
    getName2();
    getName3();
}

Future<void> getName() async {
    await getStr(); //等getStr做完
    print('name');
}

getStr() {
    print('getStr');
}

Future<void> getName2() {
    print('name2');
}

Future<void> getName3() {
    print('name3');
}
打印输出
getStr
name2
name3
name


void main() {
    Future(() => futureTask())
        .then((i) => 'abc$i') //abc10
        .then((m) => print('$m')) //abc10
        .then((w) => Future.error('出错了'))
        .whenComplete(() => print('whenComplete'))
        .catchError((e) => print(e), test: (Object o) {
        print('test');
        return false;//返回false就不会捕获,重新抛出去
    });
}

futureTask() {
    return 10;
}

打印输出
abc10
whenComplete
test
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: 出错了
null

如果改成return true
打印得到
abc10
whenComplete
test
出错了
Event-Looper

Dart中的Main Isolate只有一个Event Looper,但是存在两个Event Queue: Event Queue以及Microtask Queue。

void main(){
    testFuture();
}
void testFuture() {
    Future f = new Future(() => print('f1'));
    Future f1 = new Future(() => null);
    //Future f1 = new Future.delayed(Duration(seconds: 1) ,() => null);
    Future f2 = new Future(() => null);
    Future f3 = new Future(() => null);
    f3.then((_) => print('f2'));
    f2.then((_) {
        print('f3');
        new Future(() => print('f4'));
        f1.then((_) {
        print('f5');//微任务队列
        });
    });
    f1.then((m) {
        print('f6');
    });
    print('f7');
}
打印输出
f7
f1
f6
f3
f5
f2
f4


//微任务优先
import 'dart:async';
void main(){
    testScheduleMicrotask();
}
void testScheduleMicrotask(){
    scheduleMicrotask(() => print('s1'));

    new Future.delayed(new Duration(seconds: 1), () => print('s2'));

    new Future(() => print('s3')).then((_) {
        print('s4');
        scheduleMicrotask(() => print('s5'));
    }).then((_) => print('s6'));

    new Future(() => print('s7'));

    scheduleMicrotask(() => print('s8'));

    print('s9');
}

输出
s9
s1
s8
s3
s4
s6
s5
s7
s2



进阶
void testScheduleMicrotask() {
    scheduleMicrotask(() => print('s1'));

    new Future.delayed(new Duration(seconds: 1), () => print('s2'));

    new Future(() => print('s3')).then((_) {
        print('s4');
        scheduleMicrotask(() => print('s5'));
    }).then((_) => print('s6'));

    new Future(() => print('s10'))
        .then((_) => new Future(() => print('s11')))
        .then((_) => print('s12'));

    new Future(() => print('s7'));

    scheduleMicrotask(() => print('s8'));

    print('s9');
}

输出
I/flutter (31288): s9
I/flutter (31288): s1
I/flutter (31288): s8
I/flutter (31288): s3
I/flutter (31288): s4
I/flutter (31288): s6
I/flutter (31288): s5
I/flutter (31288): s10
I/flutter (31288): s7
I/flutter (31288): s11
I/flutter (31288): s12
I/flutter (31288): s2

生成器

同步生成器

使用sync*,返回的是Iterable对象。
yield会返回moveNext为true,并等待 moveNext 指令。

void main(){
    var it = getSyncGenerator(5).iterator;
    while (it.moveNext()) {
        print(it.current);
    }
}

Iterable<int> getSyncGenerator(int n) sync* {
    print('start');
    int k = 0;
    while (k < n) {
        yield k++;
    }
    print('end');
}
异步生成器

使用async*,返回的是Stream对象
调用getAsyncGenerator立即返回Stream, 执行了listen,函数才会开始执行。
listen返回一个StreamSubscription 对象进只有行流监听控制

import 'dart:async';

void main() {
    //getAsyncGenerator(5);
    //订阅
    StreamSubscription subscription = getAsyncGenerator(5).listen(null);
    subscription.onData((value) {
        print(value);
        if (value >= 2) {
        subscription.pause();
        }
    });
}

Stream<int> getAsyncGenerator(int n) async* {
    print('start');
    int k = 0;
    while (k < n) {
        yield k++;
    }
    print('end');
}
隔离(Isolates)

所有Dart代码都在隔离区内运行,而不是线程。每个隔离区都有自己的内存堆,确保不会从任何其他隔离区访问隔离区的状态。

##注解

@deprecated
void main() {
    dynamic tv = new Television();
    tv.activate();
    tv.turnOn();
}

class Television {
    @deprecated
    void activate() {
        turnOn();
    }

    void turnOn() {
        print('Television turn on!');
    }
}
@override
void main() {
    dynamic tv = new Television();
    tv.activate();
    tv.turnOn();
    tv.turnOff();
}

class Television {
    @deprecated
    void activate() {
        turnOn();
    }

    void turnOn() {
        print('Television turn on!');
    }
    @override
    noSuchMethod(Invocation mirror) {
        print('没有找到方法');
    }
}
自定义注解

test.dart中

class ToDo {
    final String name;
    final String what;

    const ToDo({this.name, this.what});
}

main.dart中

import 'package:flutter_app/111.dart';

void main() {
    ......
}

class Television {

@ToDo(name:'csy', what:'create')
    void doSomething() {
        print("dosomething");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值