Flutter小白實操之Dart簡介

以下內(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
  }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末代兵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子爷狈,更是在濱河造成了極大的恐慌植影,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淆院,死亡現(xiàn)場離奇詭異何乎,居然都是意外死亡句惯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門支救,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抢野,“玉大人,你說我怎么就攤上這事各墨≈腹拢” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵贬堵,是天一觀的道長恃轩。 經(jīng)常有香客問我,道長黎做,這世上最難降的妖魔是什么叉跛? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蒸殿,結(jié)果婚禮上筷厘,老公的妹妹穿的比我還像新娘。我一直安慰自己宏所,他們只是感情好酥艳,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著爬骤,像睡著了一般充石。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上霞玄,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天骤铃,我揣著相機與錄音,去河邊找鬼坷剧。 笑死劲厌,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的听隐。 我是一名探鬼主播补鼻,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼雅任!你這毒婦竟也來了风范?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沪么,失蹤者是張志新(化名)和其女友劉穎硼婿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體禽车,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡寇漫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年刊殉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片州胳。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡记焊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出栓撞,到底是詐尸還是另有隱情遍膜,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布瓤湘,位于F島的核電站瓢颅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏弛说。R本人自食惡果不足惜挽懦,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望木人。 院中可真熱鬧巾兆,春花似錦、人聲如沸虎囚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淘讥。三九已至,卻和暖如春堤如,著一層夾襖步出監(jiān)牢的瞬間蒲列,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工搀罢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蝗岖,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓榔至,卻偏偏與公主長得像抵赢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唧取,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 書籍 《Flutter實戰(zhàn)·第二版》](https://book.flutterchina.club/[https...
    wg689閱讀 647評論 0 1
  • [TOC] Flutter簡介 Flutter 是 Google推出并開源的移動應(yīng)用開發(fā)框架铅鲤,主打跨平臺、高保真枫弟、...
    修_遠(yuǎn)閱讀 228評論 0 0
  • 前言:學(xué)習(xí) Flutter 有一段時間了邢享,本篇文章主要是記錄下 Flutter 學(xué)習(xí)歷程的一些心得和開發(fā)體驗,羅列...
    沉江小魚閱讀 4,767評論 3 30
  • 我寫了一本 《Flutter實戰(zhàn)》 推薦給大家淡诗。在線閱讀地址:https://book.flutterchina...
    lazydu閱讀 12,983評論 4 15
  • Flutter環(huán)境搭建這里只介紹在macOS中Flutter的環(huán)境搭建骇塘,如需了解windows下的Flutter開...
    grr1314閱讀 583評論 2 0