Dart | 基礎學習筆記

基本數據類型

Number

  • int

    • int a = 1;
    • int b = 0xDEFFFF;
  • double

    • double x = 1.0;
  • 轉換

    • var a = int.parse('1');
    • var b = double.parse('2.5');
    • 指定進制:
      var hex = int.parse('10', radix: 16);
    • String a = 1.toString();
    • String b = 3.1415.toStringFixed(2);
      b = '3.14'

String

  • var a = 'this is a string text';
  • var b = '''
    this is a multiple line string
    text....
    ''';

Boolean

  • bool a = true;
  • bool b = 1 > 0;

List

  • var a = [1, 2, 3];
  • List<String> = ['a', 'b'];
  • [1,2,3].sort((a,b) => a.compareTo(b));

Set

  • var a = {'a', 'b'};
  • .length
  • .add()
  • .addAll(aSet)

Map

  • var aMap = Map();
  • var aMap = {};
  • Map<String, dynamic> map = {
    'a': 1,
    'b': 'hello',
    'c': ()=>print('hello')
    };
    map.forEach((key, val){
    print('key:val');
    });
  • Map<int, String> b = {0: 'a', 1: 'b'};

Rune

  • UTF-32編碼字符
  • (?) 是 \u2665
  • (?) 是 \u{1f600} -- 非4個字符的用{}包裹

函數

Function類

  • int aFunc(int a, int b) => a+b;
  • void aFunc(){}
  • aFunc(){}
  • 用{}指定命名參數
    aFunc(title: String, {Key key, @required Widget child})
  • 用[]指定可選參數
    aFunc(title: String, {Key key, @required Widget child})
  • 設置默認參數值
    aFunc(title: 'hello', {Key key, @required Widget child})
  • 匿名函數(lambda/closure):(){}
  • 函數返回類型
    Function makeAdder(num addBy) {
    return (num i) => addBy + i;
    }

運算符

算數

  • ~/
    除數取整:5 ~/ 2 = 2
  • %
    除數取余:5 % 2 = 1

類型判定

  • as:將對象強制轉換為特定類型
    (emp as Person).firstName = 'Bob';
  • is:判定對象是否是指定的類型
    obj is Object;
    is!:是上面的取反

賦值運算符

  • ??=
    b ??= 'a'; (如果b為null,則b='a',否則不變)

條件表達式

  • ? :
    a = b>0 ? 'yes' : 'no';
  • ??
    a = b ?? 'a'; (如果b為null,則a='a',否則a=b)

級聯運算符

  • .. :對同一個對像進行一系列的操作

querySelector('#confirm') // 獲取對象。
..text = 'Confirm' // 調用成員變量。
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));

上面代碼等同于:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

  • 嚴格的來講, “兩個點” 的級聯語法不是一個運算符。 它只是一個 Dart 的特殊語法。

可選類型(類似swift的Optional)

  • ?.
    a = obj?.name; (如果obj為null,則a=null;
    如果obj.name為null,a=null)

控制流程語句

if-else

for

  • for(var i=0; i<5; i++){}

  • forEach

    • [1,2,3].forEach((val) => print('val: $val'));
  • for-in

    • (for var i in [1,2,3]){}

switch-case

  • var word = 'a';
    switch(word){
    case 'b':
    print('hello b');
    break;
    default: break;
    }

assert

  • assert(text != null);
  • assert 語句只在開發環境中有效, 在生產環境是無效的;

枚舉

enum Color {

red, green, blue
}

Color.red.index == 0;

Color.values[0] == Color.red;

異常

try-catch

  • try{
    doingSomething();
    } on Exception catch(e) {
    print('明確類型的異常');
    } catch(e, s){
    print('不明確的異常:e, 堆棧:s');
    }

rethrow

finally

  • try{
    } finally {
    }
  • try{
    } catch(e) {
    } finally {
    }

Dart 是一種基于類和 mixin 繼承機制的面向對象的語言。

繼承用extends關鍵字;
實現多個接口(抽象類)用implements關鍵字;
重寫父類方法用@override關鍵字;

獲取對象的類型

  • Type aType = a.runtimeType;

實例變量

  • class Point {
    int x; // 聲明實例變量 x,初始值為 null 。
    int y; // 聲明實例變量 y,初始值為 null 。
    double z = 0; // 聲明示例變量 z,初始值為 0 。
    }
  • 所有未初始化的實例變量默認值都為 “null” ,而不是int的為0
  • 隱式生成setter和getter方法

構造函數

  • 默認構造函數

    • var p = Person();
      var p = new Person(); (new是可選的)
  • 自定義構造函數

    • Person(int age, String name){
      this.age = age;
      this.name = name;
      }
      this指代當前實例對象,跟oc中的self一樣。
      上面的代碼等同于:
      Person(this.age, this.name);
    1. 子類不會繼承父類的構造函數。 子類不聲明構造函數,那么它就只有默認構造函數 (匿名,沒有參數)。
  1. 如果希望使用父類中定義的命名構造函數創建子類, 就必須在子類中實現該構造函數。
  2. 默認情況下,子類的構造函數會自動調用父類的默認構造函數
  • 命名構造函數

    • 指定意圖的構造函數:
      Point.origin() {
      x = 0;
      y = 0;
      }
  • 父類構造函數

    • class Person {
      String firstName;

    Person.fromJson(Map data) {
    print('in Person');
    }
    }

class Employee extends Person {
// Person does not have a default constructor;
// you must call super.fromJson(data).
Employee.fromJson(Map data) : super.fromJson(data) {
print('in Employee');
}
}

main() {
var emp = new Employee.fromJson({});

// Prints:
// in Person
// in Employee
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
(emp as Person).firstName = 'Bob';
}
- // 在構造函數體執行之前,
// 通過初始列表設置實例變量。
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): (x,y)');
}

  • 工廠構造函數

    • 一個工廠構造函數可能會返回一個 cache 中的實例, 或者可能返回一個子類的實例。
    • class Logger {
      final String name;
      bool mute = false;

    // 從命名的 _ 可以知,
    // _cache 是私有屬性。
    static final Map<String, Logger> _cache =
    <String, Logger>{};

    factory Logger(String name) {
    if (_cache.containsKey(name)) {
    return _cache[name];
    } else {
    final logger = Logger._internal(name);
    _cache[name] = logger;
    return logger;
    }
    }

    Logger._internal(this.name);

    void log(String msg) {
    if (!mute) print(msg);
    }
    }

  • getters & setter

    • class Rectangle {
      num left, top, width, height;

    Rectangle(this.left, this.top, this.width, this.height);

    // 定義兩個計算屬性: right 和 bottom。
    num get right => left + width;
    set right(num value) => left = value - width;
    num get bottom => top + height;
    set bottom(num value) => top = value - height;
    }

void main() {
var rect = Rectangle(3, 4, 20, 15);
assert(rect.left == 3);
rect.right = 12;
assert(rect.left == -8);
}

  • 抽象類

    • 抽象方法只存在于 抽象類 中。
    • abstract class Doer {
      // 定義實例變量和方法 ...

    void doSomething(); // 定義一個抽象方法。
    }

class EffectiveDoer extends Doer {
void doSomething() {
// 提供方法實現,所以這里的方法就不是抽象方法了...
}
}

  • noSuchMethod()

    • 這樣可以避免一些dynamic類型的實例對象類型錯誤,導致訪問某些方法時崩潰問題;
      如Person a = null; a.name(崩潰);
    • class A {
      // 如果不重寫 noSuchMethod,訪問
      // 不存在的實例變量時會導致 NoSuchMethodError 錯誤。
      @override
      void noSuchMethod(Invocation invocation) {
      print('You tried to use a non-existent member: ' +
      '${invocation.memberName}');
      }
      }
  • Mixin

    • 為類添加功能
      用with關鍵詞,類似于swift的協議
    • class Maestro extends Person
      with Musical, Aggressive, Demented {
      Maestro(String maestroName) {
      name = maestroName;
      canConduct = true;
      }
      }
    • mixin Musical {
      bool canPlayPiano = false;
      bool canCompose = false;
      bool canConduct = false;

    void entertainMe() {
    if (canPlayPiano) {
    print('Playing piano');
    } else if (canConduct) {
    print('Waving hands');
    } else {
    print('Humming to self');
    }
    }
    }

    • 指定類型的mixin
      mixin MusicalPerformer on Musician {
      // ···
      }
  • 靜態方法/類方法

    • class Point {
      num x, y;
      Point(this.x, this.y);

    static num distanceBetween(Point a, Point b) {
    var dx = a.x - b.x;
    var dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
    }
    }

  • 靜態常量

    • class Queue {
      static const initialCapacity = 16;
      // ···
      }

泛型

<T>表示

List<String> list = ['a', 'b'];

var list = <int>[0, 1, 2];
var map = <String, dynamic>{};

限制泛型類型

  • class Foo<T extends SomeBaseClass> {
    // Implementation goes here...
    String toString() => "Instance of 'Foo<$T>'";
    }

class Extender extends SomeBaseClass {...}

泛型函數

  • T aFunc<T>(T param){
    }

import

  • import 'dart:html';
    import 'package:test/test.dart';
  • 前綴
    import 'package:lib1/lib1.dart';
    import 'package:lib2/lib2.dart' as lib2;

// 使用 lib1 中的 Element。
Element element1 = Element();

// 使用 lib2 中的 Element。
lib2.Element element2 = lib2.Element();

  • 導入一部分
    // Import only foo.
    import 'package:lib1/lib1.dart' show foo;

// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;

  • 延遲加載:讓應用在需要的時候再加載庫
    import 'package:greetings/hello.dart' deferred as hello;

當需要使用的時候,使用庫標識符調用 loadLibrary() 函數來加載庫:
Future greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
在一個庫上你可以多次調用 loadLibrary() 函數。但是該庫只是載入一次。

export

library

part

異步

返回Future/Stream

async-await關鍵字

  • Future checkVersion() async {
    var version = await lookUpVersion();
    // Do something with version
    }
  • await 表達式會阻塞代碼的執行,直到需要的對象返回為止。

Isolates

所有 Dart 代碼都在隔離區( isolates )內運行,而不是線程。

每個隔離區都有自己的內存堆,確保每個隔離區的狀態都不會被其他隔離區訪問。

typedef

自定義函數類型

typedef NetworkRequestCompletion = void Function(Error error, Map<String, dynamic> json);

元數據

元數據注釋以字符 @ 開頭

/// Deprecated: Use [turnOn] instead.

@deprecated
void activate() {
turnOn();
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372