變量
-
var關(guān)鍵詞
使用var聲明的變量,默認(rèn)是dynamic【類似于泛型】
var varA;
//賦值為整型
varA = 10;
//注意,改變變量類型是不可接受的,可以理解為swift中的類型推斷,也就是所說的類型安全。
varA = "ten";
Error: A value of type 'int' can't be assigned to a variable of type 'String'.
我也很好奇的嘗試了一下 let
let year = "2019";
Error: A value of type 'String' can't be assigned to a variable of type 'invalid-type'.
//顯然,Dart 并沒有這個(gè)關(guān)鍵詞用于限定不可變類型,不過有其它的。
Dart是面向?qū)ο蟮恼Z言,其中所有對(duì)象和類型都繼承于Object基類
注意 Object 的O是大寫的!!!
-
dynamic關(guān)鍵詞
dynamic valueT = "string value";
//可以放心的指向任意類型了
valueT = 100;
-
Object聲明的對(duì)象 、同樣能聲明一個(gè)泛型
Object objA = "string value";
objA = 100;
區(qū)別
dynamic聲明的變量可以調(diào)用可能的方法,但是別想多了這個(gè)只能讓你安全度過編譯期,在運(yùn)行期還是會(huì)檢查函數(shù)簽名的。
類似于
dynamic varA = "time";
varA.length;
varA.someFunction;
Error: get$someFunction is not a function.
varA.someFunction();
Error: someFunction$0 is not a function
//someFunction Dart的排異反應(yīng)還是有的
Object 聲明的變量,只能調(diào)用基類才有的方法
Object objA = "string value";
objA.length; //這里的效果可能就是,屏蔽了類型推斷機(jī)制。
- 靜態(tài)變量
const 關(guān)鍵詞 【注意 可以不聲明類型】
//編譯時(shí)常量
const String valueA = "hi";
const valueB = "const";
final 關(guān)鍵詞 【可不用聲明類型】
//僅能被初始化一次,使用時(shí)初始化。
final String valueA = "hi";
final valueB = "final";
思考 如果進(jìn)行類型轉(zhuǎn)換 【類型轉(zhuǎn)換實(shí)驗(yàn)】
var varA = 100;
//基于以往習(xí)慣 【錯(cuò)誤】
String varB = String(varA);
//as 【錯(cuò)誤】
String varC = varA as String;
//老老實(shí)實(shí)的 使用對(duì)象方法吧
String varD = varA.toString();
函數(shù)
Dart 中函數(shù)既可以作為參數(shù),也可以作為一個(gè)類型,函數(shù)式編程的身影~~~
- 無返回值函數(shù)
void noReturnFunction(){
print("無返回值的函數(shù)");
}
void noReturnWithParamFunction(int value) {
print(value);
print("無返回值,但有參數(shù)的函數(shù)");
}
- 有返回值的函數(shù)
bool isEqual(int a, int b){
return a==b;
}
//未顯示聲明返回值類型,返回值 是被標(biāo)記為 dynamic的。
isEqual_A(int a, int b){
return a==b;
}
插播一條,關(guān)于【函數(shù)簡(jiǎn)寫】 如果函數(shù)體僅有一條語句
bool isEqual(int a, int b){
return a==b;
}
==》省略 {}
bool isEqual(int a, int b) => return a==b;
==》省略 返回值類型
isEqual(int a, int b) => return a== b;
==》省略 return
isEqual(int a, int b) => a==b;
==》別想了,這是不可能的...
isEqual => a==b;
插播第二條,關(guān)于【函數(shù)重載】
int isEqual(String strA, String strB) {
return strA.compareTo(strB);
}
bool isEqual(int a, int b){
return a==b;
}
Error: 編譯器會(huì)告訴你,這個(gè)真的實(shí)現(xiàn)不了~~~
- 函數(shù)作為變量
var varF = (strValue) {
print("get $strValue ");
}
varF("Time");
- 使用
typedef聲明函數(shù)類型
typedef void noReturnFunction(String);
typedef String returnStringFunction(String);
...
- 函數(shù)作為參數(shù)傳遞 【想想var 和 dynamic 的聯(lián)系和區(qū)別】
var varF = () {
print("hello");
}
void printFunction(var func){
func();
}
//調(diào)用
printFunction(varF);
- 函數(shù)【可選參數(shù)】
//想起了 OC 的 ...
void mutableParamsFunction(String a, ...){
讀取參數(shù)列表 balabala...
...
}
Error: 別想了,也沒戲
//這里 [] 用于表示可選參數(shù)
void optionFunction(String a, String b, [String c]) {
...
//使用可選參數(shù)時(shí),需要判斷
if(c != null) {
...balabala
}
}
//調(diào)用
optionFunction("hi","flutter");
optionFunction("hi","flutter","option");
- 函數(shù)【可選參數(shù)命名】
void optionParamsNameFunction({String strA, String strB}) {
...balabala
}
//實(shí)際效果 在調(diào)用的時(shí)候就能看出來了
optionParamsNameFunction(strA: "hi", strB: "flutter");
【注意】 一個(gè)有趣的嘗試
optionParamsNameFunction(strB:"flutter", strA:"hi");
異步編程
Future 【感受 類似GCD 和 鏈?zhǔn)骄幊趟枷氲慕Y(jié)合體】
- 延時(shí)
//延時(shí)5秒
Future.delayed(new Duration(seconds:5),() {
...
}).then((anyThing){
...
});
Future中幾乎所有可用的方法,均會(huì)返回Future本身,為實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用創(chuàng)造了基礎(chǔ)。
- 異常拋出及其捕獲
> 1
Future.delayed(new Duration(seconds:2),(){
...
throw AssertionError("Error desc...");
}).then((anyThing){
//注意 一旦發(fā)生異常,此處代碼不會(huì)被執(zhí)行
}).catchError((e){
//捕獲異常
print(e.message);
});
> 2 then 可選參數(shù)捕獲異常
Future.delayed(new Duration(seconds:2),(){
throw AssertionError("Error desc...");
}).then((anyThing){
...
},onError:(e){
//可選參數(shù) 中捕獲到異常
print(e.message);
});
> 3 無論是或否發(fā)生異常,最終均會(huì)執(zhí)行的需求實(shí)現(xiàn)
Future.delayed(new Duration(seconds:2),(){
throw AssertionError("Error desc...");
}).then((anyThing){
...
}).catchError((e){
print(e.message);
}).whenComplete((){
...
print("do anything u want...");
});
- 異步事件同步 【相當(dāng)于 GCD柵欄】
Future.wait([
//事件一
Future.delayed(new Duration(seconds:2),(){
return "wait";
}),
//事件二
Future.delayed(new Duration(seconds:4),(){
return " me please";
})
]).then((results){
//results 相當(dāng)于整合了異步事件的所有結(jié)果到一個(gè)數(shù)組中
print(results[0] + results[1]);
}).catchError((e){
print(e);
});
- Future 函數(shù)改造
個(gè)人理解:可以將任意函數(shù) 返回值處理成Future對(duì)象
這一點(diǎn)尤其像RAC中的信號(hào)概念
//一個(gè)模擬獲取用戶名的函數(shù)
> 1 照葫蘆畫瓢
Future<String> getUserName() {
return "tom"
}
結(jié)果是編譯器報(bào)錯(cuò),大概意思就是 返回值 int 與 Future<String>類型沖突,
之后也嘗試查找了有沒有方法可以把任意類型包裝成Future對(duì)象,但沒有找到。
> 2 領(lǐng)悟到一點(diǎn)兒
Future<String> getUserName() async {
return "Saylor";
}
對(duì)一個(gè)函數(shù) 使用 async 關(guān)鍵詞表明其運(yùn)行在異步模式中時(shí),
Dart編譯器會(huì)自動(dòng)將返回值進(jìn)行Future對(duì)象封裝。
【運(yùn)行嘗試】
getUserName().then((strName){
print(strName);
}).whenComplete((){
print("complete...");
});
- 回調(diào)地獄 Callback hell 【實(shí)際指的就是 block嵌套使用的情況】
現(xiàn)有的編程經(jīng)歷中,的確很多時(shí)候熱衷于使用閉包,
但是積累到一定程度的時(shí)候往往會(huì)發(fā)現(xiàn)閉包使用過程中不可避免會(huì)出現(xiàn)嵌套。
[obj loginUserName:strName pwd:strPwd Result:^(str strUserId){
...
[obj getUserInfoWithUserId:strUserId Result:^(UserInfo * userInfo){
...
}];
}];
使用future 改善的原理其實(shí)就是,返回值是被封裝的Future對(duì)象,進(jìn)而能夠形成鏈?zhǔn)秸{(diào)用。(個(gè)人繆解)
Future<String> login(String strName, String pwd) async {
... 網(wǎng)絡(luò)請(qǐng)求 balabala...
strUserId = ...
return strUserId;
}
Future getUserInfo(String strUserId) async {
... 網(wǎng)絡(luò)請(qǐng)求 balabala...
userInfo = ...
return userInfo;
}
//調(diào)用
login("saylor","pwd").then((strUserId){
return getUserInfo(strUserId);
}).then((userInfo){
//...
});
- await 異步變同步
【注意】 該關(guān)鍵詞會(huì)阻塞當(dāng)前線程,故必須運(yùn)行在異步線程中!!!
//聲明一個(gè)異步方法
task() async {
try{
String strUserId = await login("tom","***");
UserInfo userInfo = await getUserInfo(strUserId);
...
}catch(error){
print(error.message);
}
}
這種最顯著的效果:以同步工作流的方式,去完成異步任務(wù)。
更符合猿類平時(shí)的編程習(xí)慣~~~
Stream 【流... 可以理解為 任務(wù)隊(duì)列】
同F(xiàn)uture 一樣,主要應(yīng)用于異步編程中。不同之處,在于Stream 可以將多個(gè)Future 任務(wù)組裝成工作流,并監(jiān)聽各個(gè)任務(wù)的完成情況。
String.fromFutures([
Future.delayed(new Duration(seconds:1),(){
//task 1
...
return "res_1";
}),
Future.delayed(new Duration(seconds:1),(){
//task 2
...
return "res_2";
}),
... 可以自行累加
]).listen((res){
//這里 res , 不同于 Future.wait 中所做的處理,每一個(gè)任務(wù)完成均能夠監(jiān)聽到。(多次執(zhí)行)
...
}.onError:(error){
//捕獲異常
print(error.message);
},onDone:(){
//工作流任務(wù)完成【全部完成】
});