以下內(nèi)容參考《Flutter實戰(zhàn)·第二版》
,僅為個人學(xué)習(xí)平匈、熟悉Dart語言托修,不同版本可能有稍微不一樣。
///
/// 例子來源:
/// 《Flutter實戰(zhàn)·第二版》https://book.flutterchina.club/chapter1/dart.html
///
/// 環(huán)境:
/// Flutter 3.10.1 ? channel stable ? https://github.com/flutter/flutter.git
/// Framework ? revision d3d8effc68 (7 days ago) ? 2023-05-16 17:59:05 -0700
/// Engine ? revision b4fb11214d
/// Tools ? Dart 3.0.1 ? DevTools 2.23.1
///
調(diào)用
void main() {
TestFunction().sayHi("aaa");
TestFunction().doSomething(() => print("hhh"));
TestFunction().say("A", "hello"); // A says hello
TestFunction().say("A", "hello", "bus");// A says hello with a bus
TestFunction().sayHello(who: "Bob"); // Bob say hello
Dog()..eat()..walk();
// flutter: eat
// flutter: walk with 4 foot
Dog().doSomething();
// flutter: a Dog can do like this:
// flutter: eat
// flutter: walk
// flutter: walk with 4 foot
TestAsync().testFutureDelayed();
TestAsync().testFutureWait();
TestAsync().testAsync();
TestAsync().testStream();
}
Var
class TestVar {
void defVar() {
var t = "hello, world!";
// 下面代碼在dart中會報錯曲横,因為變量t的類型已經(jīng)確定為String,
// 類型一旦確定后則不能再更改其類型不瓶。
//t = 1000;
}
void dynamicAndObject() {
// dynamic與Object聲明的變量都可以賦值任意對象禾嫉,且后期可以改變賦值的類型,這和 var 是不同的蚊丐,如:
dynamic t;
Object x;
t = "hello, world!";
x = "hi, world!";
//下面代碼沒有問題
t = 1000;
x = 1000;
// dynamic與Object不同的是dynamic聲明的對象編譯器會提供所有可能的組合熙参,
// 而Object聲明的對象只能使用 Object 的屬性與方法, 否則編譯器會報錯,如:
Object b = "";
// 正常
print(t.lenght);
// 報錯 The getter 'lenght' isn't defined for the type 'Object'.
//print(b.lenght);
// dynamic 的這個特點使得我們在使用它時需要格外注意麦备,這很容易引入一個運行時錯誤孽椰,
// 比如下面代碼在編譯時不會報錯昭娩,而在運行時會報錯:
print(t.xx); // t是字符串,沒有"xx"屬性黍匾,編譯時不會報錯栏渺,運行時會報錯
}
/// 一個 final 變量只能被設(shè)置一次,兩者區(qū)別在于:
/// const 變量是一個編譯時常量(編譯時直接替換為常量值)锐涯,final變量在第一次使用時被初始化磕诊。
void finalAndConst() {
// 可以省略String這個類型聲明
// 有警告: Use 'const' for final variables initialized to a constant value.
final str = "I am final String";
// final String str = "I am final String";
const str1 = "I am const String";
// const String str2 = "I am const String";
}
void nullSafety() {
// int i; // i = null
// print(i*8); //運行時錯誤
int i = 8; // 默認(rèn)不空,定義后初始化
int? j; // 可空纹腌,使用前判空
// 使用late后續(xù)初始化秀仲,使用前必須初始化,否則報錯
late int k;
// print(k); // The late local variable 'k' is definitely unassigned at this point.
k = 9;
print(k);
// 如果一個變量我們定義為可空類型壶笼,在某些情況下即使我們給它賦值過了,但是預(yù)處理器仍然有可能識別不出雁刷,
// 這時我們就要顯式(通過在變量后面加一個”!“符號)告訴預(yù)處理器它已經(jīng)不是null了覆劈,比如:
Function? fun;
if (i != null) {
print(i! * 8); //因為已經(jīng)判過空,所以能走到這 i 必不為null沛励,如果沒有顯式申明责语,則 IDE 會報錯
}
if (fun! != null) {
fun!();
}
fun?.call(); // fun 不為空時則會被調(diào)用
}
}
Function
可選參數(shù)[]和可選命名參數(shù)({xx,xx,...})還是不錯的
class TestFunction {
// 不指定返回類型,此時默認(rèn)為dynamic目派,不是bool
/*bool */isNoNull(String str) {
return str.isNotEmpty;
}
// 簡寫
bool isNull(String str) => str.isEmpty;
// 函數(shù)作為變量
var sayHi = (str) {
print(str);
};
// 參數(shù)為函數(shù)
void doSomething(var callback) {
callback(); // 執(zhí)行函數(shù)
}
// 用[]標(biāo)記為可選的位置參數(shù)坤候,并放在參數(shù)列表的最后面
String say(String from, String msg, [String? device]) {
var result = "$from says $msg";
if (device != null) {
result = "$result with a $device";
}
return result;
}
// 可選的命名參數(shù),使用{param1, param2, …}企蹭,放在參數(shù)列表的最后面白筹,用于指定命名參數(shù)
// 注意,不能同時使用可選的位置參數(shù)和可選的命名參數(shù)
void sayHello({required String who}) {
print("$who say hello");
}
}
mixin
class Dog with Eat, Walk {
@override
walk() {
print("walk with 4 foot");
}
doSomething() {
print("a Dog can do like this: ");
eat();
super.walk();
walk();
}
}
class Man extends Persson with Eat, Walk, Code {}
class Persson {
say() {
print("say");
}
}
mixin Eat {
eat() {
print("eat");
}
}
mixin Walk {
walk() {
print("walk");
}
}
mixin Code {
code() {
print("code");
}
}
Async
class TestAsync {
void testFutureDelayed() {
print("Future.delayed 2s after exec something");
Future.delayed(const Duration(seconds: 2), () {
print("Future.delayed hello");
throw AssertionError("delayed error"); // 根據(jù)是否有onError或catchError執(zhí)行
}).then((data) {
// 成功走這里
print("Future.delayed success");
}, onError: (e) {
print("Future.delayed onError $e"); // 加了onError谅摄,不走catchError
}).catchError((e) {
// 失敗走這里 then沒加onError徒河,不走then,走catchError
print("Future.delayed catchError $e");
}).whenComplete(() {
print("Future.delayed complete"); // 無論成功或失敗都走這里
});
// flutter: Future.delayed 2s after exec something
// flutter: Future.delayed hello
// flutter: Future.delayed onError Assertion failed: "delayed error"
// flutter: Future.delayed complete
}
// 等待多個異步任務(wù)都執(zhí)行結(jié)束后才進(jìn)行一些操作
// Future.wait([]), 數(shù)組中所有Future都執(zhí)行成功后送漠,才會觸發(fā)then的成功回調(diào), 只要有一個Future執(zhí)行失敗顽照,就會觸發(fā)錯誤回調(diào)
void testFutureWait() {
print("Future.wait start after 4s show something");
Future.wait([
Future.delayed(const Duration(seconds: 2), () {
return "Hi";
}),
Future.delayed(const Duration(seconds: 4), () {
return " Bob";
}),
]).then((results) {
print("Future.wait ${results[0]}${results[1]}");
}).catchError((e) {
print(e);
}).whenComplete(() {
print("Future.wait complete");
});
// flutter: Future.wait start after 4s show something
// flutter: Future.wait Hi Bob
// flutter: Future.wait complete
}
void testAsync() {
testAsync1();
testAsync2();
testAsync3();
testAsync4();
// flutter: testAsync1
// flutter: testAsync2 pre //有await,after
// flutter: testAsync3
// flutter: testAsync4 pre //沒有await闽寡,直接after
// flutter: testAsync4 after //沒等待
//
// flutter: testAsync2 in //等待2s后
// flutter: testAsync2 after
// flutter: testAsync4 in
}
void testAsync1() {
print("testAsync1");
}
void testAsync2() async {
print("testAsync2 pre");
await Future.delayed(const Duration(seconds: 2), () {
print("testAsync2 in");
});
print("testAsync2 after");
}
void testAsync3() {
print("testAsync3");
}
void testAsync4() async {
print("testAsync4 pre");
/*await*/ Future.delayed(const Duration(seconds: 5), () {
print("testAsync4 in");
});
print("testAsync4 after");
}
void testStream() {
Stream.fromFutures([
// 1秒后返回結(jié)果
Future.delayed(const Duration(seconds: 1), () {
return "Stream hi 1";
}),
Future.delayed(const Duration(seconds: 2), () {
throw AssertionError("Stream error");
}),
Future.delayed(const Duration(seconds: 3), () {
print("Stream hi 3");
}),
]).listen((data) {
print("Stream listen $data");
}, onError: (e) {
print("Stream error $e");
}, onDone: () {
print("Stream Done");
});
// flutter: Stream listen Stream hi 1
// flutter: Stream error Assertion failed: "Stream error"
// flutter: Stream hi 3
// flutter: Stream listen null
// flutter: Stream Done
}