參考《Flutter實(shí)戰(zhàn)》
獨(dú)特語(yǔ)法:
1灾锯、可選命名參數(shù)
2粘姜、..(級(jí)聯(lián)操作符)
3、?.(條件成員訪問(wèn)運(yùn)算符)
4颤难、??(判空賦值運(yùn)算符)
一些比較特別的語(yǔ)法
var 可接收任何類(lèi)型變量爽室,一旦賦值汁讼,類(lèi)型就確定
如:
var t ;
t = "hello world";
t = 100;(此時(shí)報(bào)錯(cuò))
dynamic/Object
dynamic和object聲明的變量可以賦值任何對(duì)象,而且可以隨時(shí)改變
如:
dynamic a;
Object b;
a = "hello world";
b = "hi world";
// 下面的代碼可以通過(guò)編譯
a = 100;
b = 100;
dynamic和Object不同的地方在于阔墩,dynamic聲明的對(duì)象編譯器可以提供所有可能
變量的方法使用嘿架,而Object則不提供
如:接上面代碼
a = "hello world";
b = "hi world";
print(a.length);
// 下面會(huì)報(bào)錯(cuò)
print(b.length);
final、const
被兩者修飾的變量啸箫,都是常量耸彪,值只能被設(shè)置一次;不同在于final是第一次使用時(shí)被初始化
const是編譯時(shí)常量
且使用者兩個(gè)忘苛,變量類(lèi)型可忽略
如:
final a = "hello world";
const b = "hi world";
函數(shù):
Dart函數(shù)聲明如果沒(méi)有顯式聲明返回值類(lèi)型時(shí)會(huì)默認(rèn)當(dāng)dynamic處理
如:
typedef bool CALLBACK();
// 返回類(lèi)型為dynamic
isNoble(int number) {
return _nobleGases[number] != null;
}
// 需要傳入bool函數(shù)
void test(CALLBACK cb) {
print(cb());
}
// 報(bào)錯(cuò) isNoble不是bool類(lèi)型
test(isNoble)蝉娜;
函數(shù)里面只有一個(gè)表達(dá)式,可以使用簡(jiǎn)寫(xiě)語(yǔ)法
如:
bool isNoble(int number) => _nobleGases[number] != null扎唾;
函數(shù)作為一個(gè)變量
var say = (str) {
print(str);
}
say("hello world")召川;
函數(shù)作為參數(shù)傳遞
void dothing(var callback) {
callback();
}
dothing(() => print("xxx"));
可選的位置參數(shù) []標(biāo)記的參數(shù)為可選參數(shù)
如:
String say(String from,String msg,[String to]) {
var result = '$from says $msg';
if (to != null) {
result = '$result with a $to';
}
return result;
}
可選命名參數(shù) 使用{params1, params2,...}
如:
// 設(shè)置[flag]和[msg]標(biāo)志
void sendMsg({bool flag,String msg}){
//...
}
//調(diào)用
sendMsg(flag:true,msg:"hello world");
異步支持:
Future(有點(diǎn)類(lèi)似Rxjava):表示一個(gè)異步操作的最終結(jié)果胸遇,異步成功荧呐,就執(zhí)行成功后的操作;失敗就捕獲錯(cuò)誤或停止后續(xù)操作纸镊。
一個(gè)Future只會(huì)對(duì)應(yīng)一個(gè)結(jié)果;Future所有API返回的還是Future對(duì)象倍阐,因此可用于鏈?zhǔn)秸{(diào)用
Future.then 接收異步結(jié)果 (對(duì)應(yīng)Rxjava中的onNext())
Future.catchError 異步發(fā)生錯(cuò)誤,可以捕獲 (對(duì)應(yīng)Rxjava中的onError())
Future.whenComplete 異步完成 (對(duì)應(yīng)Rxjava中的onComplete()薄腻,不過(guò)在Rxjava中onError和onComplete只執(zhí)行一個(gè),此處whenComplete無(wú)論如何都會(huì)執(zhí)行)
如:
Future.delayed(new Duration(seconds:2),()) {
return "hello world";
}).then((data){
// 正常執(zhí)行結(jié)束會(huì)執(zhí)行下面代碼
print(data);
}).catchError((e){
// 執(zhí)行過(guò)程發(fā)生異常會(huì)執(zhí)行下面代碼
print(e);
}).whenComplete((){
// 成功失敗都會(huì)執(zhí)行下面代碼
print("done");
});
Future.wait 等待多個(gè)異步任務(wù)完成才進(jìn)行操作(類(lèi)似Rxjava中的flatMap,)
Future.wait([
// 2秒后返回結(jié)果
Future.delayed(new Duration(second:2),(){
return "hello";
})收捣,
// 4秒后返回結(jié)果
Future.delayed(new Duration(second:4),(){
return "world";
})
]).then((results){
print(results[0] + reults[1]);
}).catchError((e){
print(e);
})
Async/await
async 用來(lái)表示函數(shù)異步,會(huì)返回一個(gè)Future對(duì)象庵楷,可以使用then方法添加回調(diào)函數(shù)
await后面是一個(gè)Future罢艾,表示等待該異步任務(wù)完成,異步完成后才往下走(阻塞)
如:傳統(tǒng)的Future鏈?zhǔn)秸{(diào)用(模擬登陸)
// 定義異步任務(wù)
// 登陸
Future<int> login(String username,String pwd) {}
// 獲取用戶信息
Future<String> getUserInfo(int userId){}
// 保存用戶信息
Future saveUserInfo(String userInfo){}
// 鏈?zhǔn)秸{(diào)用
Future("baiaj","123456").then((id){
return getUserInfo(id);
}).then((userInfo){
return saveUserInfo(userInfo);
}).then((e){
// 執(zhí)行接下來(lái)操作
}).catchError((e){
// 錯(cuò)誤處理
print(e);
})
使用async/await消除callback hell(回調(diào)地獄)
task() async {
int id = await login("baiaj","123456");
String userInfo = await getUserInfo(id);
await saveUserInfo(userInfo);
// 執(zhí)行接下來(lái)操作
}
Stream
可用于接收異步事件數(shù)據(jù)尽纽,在執(zhí)行異步任務(wù)時(shí)咐蚯,可以通過(guò)多次觸發(fā)成功或失敗事件來(lái)傳遞結(jié)果數(shù)據(jù)和錯(cuò)誤
常用于網(wǎng)絡(luò)任務(wù)下載 ,文件讀寫(xiě)等弄贿。
Stream.fromFutures([
// 1秒后返回結(jié)果
Future.delayed(new Duration(second:1),(){
return "hello 1";
}),
// 2秒后拋出一個(gè)異常
Future.delayed(new Duration(second:2),(){
return AssetitonError("Error")春锋;
}),
// 3秒后返回結(jié)果
Future.delayed(new Duration(second:3),(){
return "hello 3";
})
]).listen((data){
print(data);
},onError:(e){
print(e.message);
},onDone:(){
// 完成
});
操作符
.. 級(jí)聯(lián)操作符(允許對(duì)同一對(duì)象執(zhí)行一系列操作)
如:
// 普通調(diào)用
var button = getButton();
button.text = 'hello world';
button.classes.add('imp');
button.onClick.listen((e)=>window.alert('confirmed'));
// 級(jí)聯(lián)操作
getButton()
..text = 'hello world'
..classes.add('imp')
..onClick.listen((e)=>windown.alert('confirmed'));
?.(條件成員訪問(wèn)運(yùn)算符)
獲取成員,但是左邊的對(duì)象可以為null
如
UserInfo userInfo = new UserInfo();
String name = userInfo.name;
UserInfo userInfo2;
// 此時(shí)userInfo2為null差凹,獲取的name為null
name = userInfo?.name;
??(判空賦值運(yùn)算符)
var a = null;
String b = "hello world";
// 如果a為null期奔,則返回b,否則返回b
// 此處返回b
var result = a ?? b;
print(result);