Flutter入门——Dart语法

Dart语言由Google公司提出

  • 基于 AOT(ahead of time) 的发布包:在发布时可以通过 AOT 生成高效的机器码以保证应用性能。而 JavaScript 则不具有这个能力。
  • 基于 JIT (just in time)的快速开发周期: 在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;
    因此是一种开发高效、执行简单的语言。其特殊的热重载功能,在开发中能实时刷新安卓页面而不用重新打包。

数据类型

数据类型.PNG
  • 未初始化的数据类型都是null,包括数字和布尔类型

变量与常量

  1. 显示指定类型
String name = "张三";
num age = 18;
  1. 使用var,隐式定义
var address = "日落大道";
var id = 108;

3.动态改变类型的变量采用ObjectDynamic定义

Object var1 = '1';
var1 = 1;
Dynamic var2 = 2;
var2 = 'hello';
  1. 常量采用finalconst修饰
    final 运行时常量
    const 编译时常量
final time = new DateTime.now(); // 正确
const time = new DateTime.now(); // 错误
const list = const[1,2,3];       // 正确
const list = [1,2,3];            // 错误

字符串

  1. 单引号、双引号都可
  2. ''' '''或""" """可包含多行
  3. 字符串前加r可不加转义符
  4. ${}可进行字符串拼接,变量可省略大括号,表达式必须带括号
// 当仅取变量值时,可以省略花括号
var aStr2 = "hello,$name"; // hello,王五

// 当拼接的是一个表达式时,则不能省略花括号
var str1 = "link";
var str2 = "click ${str1.toUpperCase()}";
print(str2);   // click LINK

列表

和Java类似

var list = [1,2,3];
var list = const[1,2,3];//不可变

映射

相当于Java的HashMap

// 1.通过字面量创建Map
var gifts = {
  'first' : 'partridge',
  'second': 'turtledoves',
  'fifth' : 'golden rings'
};

// 2.使用Map类的构造函数创建对象
var pic = new Map();
// 往Map中添加键值对
pic['first'] = 'partridge';
pic['second'] = 'turtledoves';
pic['fifth'] = 'golden rings';

函数

  1. 函数也是对象,类型是function
  2. 可赋值给变量,也可当作其他函数的参数
  3. 所有函数都有返回值,不写返回null

函数类型

  • 命名可选参数: 根据参数名传值
  • 位置可选参数:根据参数位置传值
///命名可选参数
// 定义一个函数,参数列表用花括号包裹
enableFlags({bool bold, bool hidden}) {
    // do something
}

// 调用方式,传参时使用"参数名:值"的形式
enableFlags(hidden:true, bold:false);

///位置可选函数
// 定义add函数
add(int x, [int y, int z]){
    int result = x;
    if (y !=  null){
        result = result + y;
    }

    if (z !=  null){
        result = result + z;
    }
    print(result);
}

// 调用
add(18);           // 18
add(18,12);        // 30
add(18, 12, 15);   // 45

匿名函数
匿名函数是一个lambda表达式或闭包
与普通函数一样有参数列表,函数体,只是没有函数名

// 定义匿名函数,并将其赋值给一个变量func
//注意,函数体最后的花括号处必须有分号结束。
var func = (x,y){
    return x + y;
};

箭头函数
函数体只有return语句可简写

add(num x, num y) => x+y;
//匿名箭头函数
var function = add(num x, num y) => x+y;

运算符

基本和Java相同,包含+,-,*,/,%,另外增加一个~/运算符代表整除。
条件表达式
支持三目表达式condition ? expr1 : expr2
判空表达式 ??expr

//若expr1不为空返回expr1的值,若expr1为空则返回expr2
expr1 ?? expr2

级联运算符
..连续调用类的多个方法

new Person()..setName("Bob")..setAge(20)..save();

分支与循环

条件分支

  • if分支与Java相同
  • switch分支case可使用整数、字符串、枚举类型和编译时常量
    循环
  • 基本循环与Java类似
  • 特有循环
var myList = ['Java','JavaScript','Dart'];

// for...in...循环,类似Java中的增强for
for (var it in myList ){
    print(it);
}

// forEach循环。其参数为一个Function对象,这里传入一个匿名函数
myList.forEach((var it){
    print(it);
});

// 可以使用匿名箭头函数简写
myList.forEach((it) => print(it));
var myMap = {
'zhangsan':'201901',
'lisi':'201902',
'wangwu':'201902'
};

// forEach遍历Map
myMap.forEach((k, v) =>  print("$k : $v"));

// 根据键获取值来遍历。通过keys返回Map中所有键的集合
for(var k in myMap.keys){
    print("$k : ${myMap[k]}");
}

mixin

Dart不支持多继承,但支持mixinmixin修饰的类可以用with进行组合

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{}

异步支持

Future函数

//Future.then  接收异步结果
Future.delayed(Duration(seconds: 2),(){
   return "hi world!";
}).then((data){
   print(data);
});
//Future.catchError 捕获异步错误
Future.delayed(Duration(seconds: 2),(){
   //return "hi world!";
   throw AssertionError("Error");  
}).then((data){
   //执行成功会走到这里  
   print("success");
}).catchError((e){
   //执行失败会走到这里  
   print(e);
});
//Future.whenComplete //异步请求完成回调
Future.delayed(Duration(seconds: 2),(){
   //return "hi world!";
   throw AssertionError("Error");
}).then((data){
   //执行成功会走到这里 
   print(data);
}).catchError((e){
   //执行失败会走到这里   
   print(e);
}).whenComplete((){
   //无论成功或失败都会走到这里
});
//Future.wait //接受异步`Future`数组参数,只有所有操作执行成功才进入`then`回调,否则触发错误回调
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

回调地狱(Callback Hell)
如果代码中有大量异步逻辑,并且出现大量异步任务依赖其它异步任务的结果时,必然会出现Future.then回调中套回调情况。举个例子,比如现在有个需求场景是用户先登录,登录成功后会获得用户ID,然后通过用户ID,再去请求用户个人信息,获取到用户个人信息后,为了使用方便,我们需要将其缓存在本地文件系统,代码如下:

//先分别定义各个异步任务
Future login(String userName, String pwd){
    ...
    //用户登录
};
Future getUserInfo(String id){
    ...
    //获取用户信息 
};
Future saveUserInfo(String userInfo){
    ...
    // 保存用户信息 
}; 
login("alice","******").then((id){
 //登录成功后通过,id获取用户信息    
 getUserInfo(id).then((userInfo){
    //获取用户信息后保存 
    saveUserInfo(userInfo).then((){
       //保存用户信息,接下来执行其它操作
        ...
    });
  });
})

如果业务逻辑中有大量异步依赖的情况,将会出现上面这种在回调里面套回调的情况,过多的嵌套会导致的代码可读性下降以及出错率提高,并且非常难维护,这个问题被形象的称为回调地狱(Callback Hell

使用Future消除Callback Hell

login("alice","******").then((id){
    return getUserInfo(id);
}).then((userInfo){
    return saveUserInfo(userInfo);
}).then((e){
   //执行接下来的操作 
}).catchError((e){
  //错误处理  
  print(e);
});

使用 async/await 消除 callback hell

task() async {
   try{
    String id = await login("alice","******");
    String userInfo = await getUserInfo(id);
    await saveUserInfo(userInfo);
    //执行接下来的操作   
   } catch(e){
    //错误处理   
    print(e);   
   }  
}

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: (){

});

全文参考
Dart语言基础语法
Flutter实战·第二版

你可能感兴趣的:(Flutter入门——Dart语法)