变量
普通:
bool b ;
b = true;
string a = '';
var
//这样命名和普通命名一样
var string a;
a = '';
// var 也可以不声明类型(可以接收任何类型的变量),一旦赋值不能修改。
var t;
t = "hi world";
// 下面代码在dart中会报错,因为变量t的类型已经确定为String,
// 类型一旦确定后则不能再更改其类型。
t = 1000;
final 和 const
//用final 和 const 声明变量,变量不能修改
//const 变量是一个编译时常量,final变量在第一次使用时被初始化
//可以省略String这个类型声明
final str = "hi world";
//final String str = "hi world";
const str1 = "hi world";
//const String str1 = "hi world";
dynamic和Object
//Object 是Dart所有对象的根基类,所以任何类型的数据都可以赋值给Object声明的对象.
//dynamic与var一样都是关键词,声明的变量可以赋值任意对象。 而dynamic与Object相同之处在于,他们声明的变量可以在后期改变赋值类型。
dynamic t;
Object x;
t = "hi world";
x = 'Hello Object';
t = 1000;
x = 1000;
//变量a不会报错, 变量b编译器会报错
dynamic a = '';
Object b = '';
print(a.length);
// warning:
// The getter 'length' is not defined for the class 'Object'
print(b.length);
//[注]dynamic的这个特性与Objective-C中的id作用很像. dynamic的这个特点使得我们在使用它时需要格外注意,这很容易引入一个运行时错误.
函数
//一般写法
int add:(int a , ini b){
return a+b;
}
//如果函数里边只有一句可以简写如下:( "=>" 写法)
int add:(int a , ini b) => return a+b;
//函数作为变量
var say = (str){
print(str);
};
say("hi world");
//函数可以作为变量,实现回调(oc 的block)
void textCallBack(var callBack){
int a = 10;
callBack(a);
}
void showCallBack(){
textCallBack((int a){
print(a);
});
}
//可以简写为:
void showCallBack() => textCallBack((int a) => print(a));
//可以选固定参数(常用)
void textP(int a, {int b,int c}){
print('$a' + b + '$c' + d);
}
void showtextP(){
textP(10);//yes
textP(10,c: 10,);//yes
}
//在Widget 里边是这样命名可选,实现构造函数
class StateMsg extends StatefulWidget {
final a;
const StateMsg({Key key, this.a}) : super(key: key);
}
//可选位置参数
//使用[] ,标记里边的参数是可选的,String d = 'ni hao' 给参数加上默认值
void textp (int a,[String b, String d = 'ni hao', bool c]){
print('$a' + '$b' + '$c');
}
//调用用时可选参数必须依次赋值,如果想指定某个位置上的参数值,则必须前面位置的已经有值,(有默认值也不行)
void showtextP(){
textp(10);//yes
textp(10,true);//error
textp(10,'b',true);//error
textp(10,'b','d',true);//yes
}
异步
async 和 wait
// async 修饰 request 方法,表示当前方法为异步方法
// await 修饰请求,表示当前任务为耗时炒作,需要等待响应
// async 和 wait 是配套使用的
void request async (){
final response = await http.get('https://xxx');
}
Future:表示一个异步操作的最终完成(或失败)及其结果值的表示。
//拓展一下上边的例子
Future<List<>> _getDatas() async {
final response = await http.get('https://xxx');
if (response.statusCode == 200) {
return [];
} else {
throw Exception('statusCode:${response.statusCode}');
}
}
// Future.then 处理成功成功
// Future.catchError 处理失败
// Future.whenComplete 表示网络处理完成(失败和成功都会执行,可以处理一些特定的逻辑)
_getDatas().then((datas) {
print(成功);
}).catchError((error) {
print(error);
}).whenComplete((){
print(完成);
});
回调地狱(Callback Hell):异步任务依赖;比如登录->获取用户信息->保存用户信息(oc 可以使用group,栅栏函数,信号,等等的方法,来预防block里嵌套方法)
//先分别定义各个异步任务
Future<String> login(String userName, String pwd){
//用户登录
};
Future<String> getUserInfo(String id){
//获取用户信息
};
Future saveUserInfo(String userInfo){
// 保存用户信息
};
// 接下来,执行整个任务流:
login("alice","******").then((id){
//登录成功后通过,id获取用户信息
getUserInfo(id).then((userInfo){
//获取用户信息后保存
saveUserInfo(userInfo).then((){
//保存用户信息,接下来执行其它操作
});
});
});
// 这就是回调地狱,这种代码可读性低,出错率较高,并且非常难维护;可以使用Future.then 来完美的处理
// 因为方法的返回都是Future 对象,所以可以很方便的进行链式调用,这样依次向下,就避免了层层嵌套。
login("alice","******").then((id){
return getUserInfo(id);
}).then((userInfo){
return saveUserInfo(userInfo);
}).then((data){
//成功
}).catchError((e){
//错误处理
});
//也可以使用 async 和 wait 来避免
task() async {
try{
String id = await login("alice","******");
String userInfo = await getUserInfo(id);
await saveUserInfo(userInfo);
//执行接下来的操作
} catch(e){
//错误处理
print(e);
}
}
Stream 接收多个异步操作的结果(Future 只能接收一个,用法相似,不用过多表述)
常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等
Stream.fromFutures([
// 1秒后返回结果
Future.delayed(new Duration(seconds: 1), () {
return "hello 1";
}),
// 抛出一个异常
Future.delayed(new Duration(seconds: 2),(){
throw AssertionError("Error");
}),
// 3秒后返回结果
Future.delayed(new Duration(seconds: 3), () {
return "hello 3";
})
]).listen((data){
//成功
print(data);
}.onError: (e){
//错误
print(e.message);
},onDone: (){
//完成
});
//输出
I/flutter (17666): hello 1
I/flutter (17666): Error
I/flutter (17666): hello 3
网友评论