1 方法
1.1 一等方法對象 Function
void fun() {
print('hhaha');
}
void main() {
Function f = fun; // 方法都是對象否彩,可以賦值給Function對象
f(); // 調用fun()方法
}
Function還可以作為參數(shù)傳入
void fun2(Function function) { // 沒有辦法標識要傳遞的這個方法參數(shù)和返回值
print('hhaha222');
function(); // 調用傳入的方法疯攒,無參。如果傳入的方法是有參的列荔,運行時報錯
}
void main() {
Function f2 = fun2; // 方法都是對象敬尺,可以賦值給Function對象
// f2(); // 運行報錯,需要傳參
f2(f); // 調用fun2()方法贴浙,傳入方法
// 也可以傳入一個匿名方法
f2(() {
print('傳入的方法參數(shù)是匿名方法'); // 不會執(zhí)行砂吞,需要在fun2中調用才會執(zhí)行。
});
// 匿名方法可以隨意定義參數(shù)和返回值
// 在fun2需要調用時悬而,傳入的參數(shù)需要和這里定義的參數(shù)類型呜舒、數(shù)量相同,否則會運行報錯。
// 這就有些不方便了袭蝗,那如果傳入的參數(shù)錯誤唤殴,有什么辦法可以在編譯器就能檢查出來呢?這就要引入typedef關鍵字了到腥。
f2((int a, int b) {
return "1";
});
typedef關鍵字的使用
// 定義一個類型朵逝,F(xiàn)類型,這個F類型其實就是一個方法乡范,接收兩個int參數(shù)配名,返回void
typedef void F(int i, int j);
定義一個方法,將F作為參數(shù)傳入晋辆。
void fun3(F f) {
f(1, 2); // 這邊在編譯時就會校驗傳參是否正確渠脉。
print('hhaha3333');
}
調用fun2()方法
// 方法1
Function f3 = fun3;
f3((int i, int j) { // 這邊好像要在運行時才會報錯。
});
// 方法2
fun3((i, j) { // 這邊在編譯時也就會校驗傳參是否正確瓶佳。
});
如果不想使用typedef芋膘,直接將方法的原形作為參數(shù)傳入也是可以的
void fun4(void f1(int i, int j)) { // 這種寫法可以表達傳遞的這個方法參數(shù)和返回值,但寫起來比較麻煩
f1(1, 2);
}
使用場景示例:
如果我們之前在java中設置一個onClick監(jiān)聽霸饲,需要傳入接口为朋,并實現(xiàn)接口的方法。但在dart中就可以直接傳入一個方法接口厚脉。
typedef void onClick();
void setOnClickListener(onClick click){
click(); // 通過這種方式就可以直接回調出去了习寸。
}
1.2 可選位置參數(shù)
可以當做是為了解決java中的方法重載問題。
如果我們提供了同一個方法名的兩個方法傻工,只是傳入的參數(shù)不同霞溪。fun(int a)、fun(int a精钮,int b)
在dart中威鹿,我們只需要提供一個方法fun(int a,int b)即可轨香,讓使用者決定傳入哪個忽你。只需要加上中括號即可
void fun(int a, int b) {}
// 可選位置參數(shù)
void fun1([int aa = 0, int bb = 0]) {
// 最新的版本中一定要給一個默認值,否則編譯報錯臂容。之前版本好像沒問題
}
void main() {
fun(1, 2); // 必須傳兩個參數(shù)
fun1(); // 可以不傳參數(shù)
fun1(1); // 也可以只傳一個科雳,1會賦值個aa。如果要傳bb參數(shù)脓杉,aa必須要傳
fun1(1, 2); // 也可以傳兩個
}
1.3 可選命名參數(shù)
與可選位置參數(shù)不同的是糟秘,中括號改成大括號,就是可選命名參數(shù)
// 可選命名參數(shù)
void fun2({int aa = 0, int bb = 0}) {
// 最新的版本中一定要給一個默認值球散,否則編譯報錯尿赚。之前版本好像沒問題
}
void main() {
fun2(); // 不傳參數(shù),也沒問題
// fun2(1); // 只傳一個參數(shù),這樣寫就不行了凌净。需要給傳入的這個值命名
fun2(aaa: 1); // 帶入變量名悲龟,就可以給任意一個值傳值了。
fun2(bbb: 2);
fun2(bbb: 2, aaa: 1); // 順序也可以隨便傳
}
1.4 默認參數(shù)值
可選位置參數(shù)和可選命名參數(shù)都使用到了默認參數(shù)值冰寻。
1.5 匿名方法
沒有方法名的方法
void fun(Function function) {}
void main() {
fun(() {
});
fun((int, String) {
});
}
2 異常
void fun() {
throw Exception();
}
void main() {
// fun(); // 不需要像java中一樣調用try-catch须教。但是也支持
try {
fun();
} catch (e) {
// 不需要聲明類型,傳入一個變量名斩芭。e就是拋出的異常對象
print(e);
}
try {
fun();
} catch (e, a) {
// 打印結果:Exception
print(e);
// 也可以傳入兩個變量名轻腺。第二個參數(shù)是StackTrace 調用棧信息。打印結果:
// #0 fun (package:untitled/%E5%BC%82%E5%B8%B8/%E5%BC%82%E5%B8%B8.dart:2:3)
// #1 main (package:untitled/%E5%BC%82%E5%B8%B8/%E5%BC%82%E5%B8%B8.dart:16:5)
// #2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
// #3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
print(a);
}
}
在dart中可以拋出任意一種類型
void fun() {
// throw Exception(); // 在dart中不光可以拋出一個異常
// throw Error(); // 還可以拋出error
// throw 1; // 還可以拋出一個int值
// throw "異常信息"; // 拋出一個字符串
throw fun2; // 甚至是一個方法划乖、類
}
void fun2() {
print("我是一個方法");
}
根據(jù)不同的異常類型進行不同的處理
// 在catch前添加on+拋出類型贬养。
void main() {
try {
fun();
} on Function catch (e) {
print("拋出了一個方法 $e");
e(); // 如果拋出的是一個方法,甚至可以直接在這里調用這個方法琴庵。
} on int catch (e) {
print("拋出了一個int值 $e");
} on String catch (e) {
print("拋出了一個字符串 $e");
} on MissingPluginException catch (e) {
print("拋出了一個MissingPluginException異常 $e");
} on Exception catch (e) {
print("拋出了一個Exception異常 $e");
} finally { // finally用法和java一樣
}
}