dart語(yǔ)言學(xué)習(xí)筆記-1

重要觀念

參考

  • 萬般皆對(duì)象乒裆,所有對(duì)象都是繼承自O(shè)bject類碗誉。不要求所有代碼都必須定義在class中

  • Dart是強(qiáng)類型語(yǔ)言死讹,但也支持類型推斷瞒滴。

  • 支持泛型。

  • 支持頂級(jí)函數(shù)(如main()),也支持函數(shù)的嵌套赞警。

  • 支持頂級(jí)變量妓忍。

  • 不支持 public, protected, 和private關(guān)鍵字,如果以下劃線(_)開頭定義愧旦,則為私有世剖。

  • 所有的定義支持字母或下劃線開頭,后面緊跟字母笤虫、下劃線或數(shù)字旁瘫。

  • 包括expressions(條件表達(dá)式,擁有運(yùn)行時(shí)的值琼蚯,如condition ? expr1 : expr2)和statements(聲明表達(dá)式酬凳,不擁有運(yùn)行時(shí)的值,如if-else)遭庶,statements經(jīng)常包含一致多個(gè)expressions宁仔,而expressions不能直接包含statements

  • Dart tools 只匯報(bào)兩種類型的問題: warningserrors罚拟, Warnings 只提示代碼可能不工作台诗,但不會(huì)阻止程序的執(zhí)行完箩,Errors發(fā)生在編譯或者運(yùn)行期,編譯期的錯(cuò)誤會(huì)中斷代碼執(zhí)行拉队,運(yùn)行期的錯(cuò)誤會(huì)導(dǎo)致程序運(yùn)行發(fā)生異常弊知。

類型聲明規(guī)則

  1. 不能明確類型的地方需要顯示聲明類型,如方法的參數(shù)粱快、返回值
install(id, destination) => ...//bad
Future<bool> install(PackageId id, String destination) => ...//good
  1. 避免在本地變量初始化的時(shí)候聲明類型秩彤,
var desserts = <List<Ingredient>>[];//good
List<List<Ingredient>> desserts = <List<Ingredient>>[];//bad

List<AstNode> parameters;//good 未能推斷出類型,需要明確類型
  1. 避免在函數(shù)表達(dá)式上注釋推斷的參數(shù)類型事哭。
var names = people.map((person) => person.name);//good
var names = people.map((Person person) => person.name);//bad
  1. 避免在泛型調(diào)用上使用冗余類型參數(shù)漫雷。
Set<String> things = Set();//good
Set<String> things = Set<String>();//bad

var things = Set<String>();//good
var things = Set();//bad
  1. 如果推斷的類型不正確,需要聲明類型
// good
num highScore(List<num> scores) {
  num highest = 0;
  for (var score in scores) {
    if (score > highest) highest = score;
  }
  return highest;
}

/** bad
當(dāng)scores包含double類型時(shí)鳍咱,如[1.2]降盹,當(dāng)賦值給highest是會(huì)發(fā)生異常,因?yàn)閔ighest是num類型谤辜,而非num類型
**/
num highScore(List<num> scores) {
  var highest = 0;
  for (var score in scores) {
    if (score > highest) highest = score;
  }
  return highest;
}
  1. 更喜歡用動(dòng)態(tài)注釋而不是讓推理失敗蓄坏。
    Dart在類型推斷失敗的情況下,會(huì)默認(rèn)為dynamic類型丑念,如果dynamic類型是你真正想要的涡戳,那么最好在聲明時(shí)賦予
dynamic mergeJson(dynamic original, dynamic changes) => ...//good

mergeJson(original, changes) => ...//bad
  1. 首選函數(shù)類型批注中的簽名。
bool isValid(String value, bool Function(String) test) => ...//good
bool isValid(String value, Function test) => ...//bad
//good
void handleError(void Function() operation, Function errorHandler) {
  try {
    operation();
  } catch (err, stack) {
    if (errorHandler is Function(Object)) {
      errorHandler(err);
    } else if (errorHandler is Function(Object, StackTrace)) {
      errorHandler(err, stack);
    } else {
      throw ArgumentError("errorHandler has wrong signature.");
    }
  }
}
  1. 不要為setter指定返回類型脯倚。
void set foo(Foo value) { ... }//bad
set foo(Foo value) { ... }//good
  1. 不要使用舊的typedef語(yǔ)法渔彰。
//舊,bad
typedef int Comparison<T>(T a, T b);
typedef bool TestNumber(num);
//新推正,good
typedef Comparison<T> = int Function(T, T);
typedef Comparison<T> = int Function(T a, T b);
  1. 首選內(nèi)聯(lián)函數(shù)類型而不是typedef恍涂。
class FilteredObservable {
  final bool Function(Event) _predicate;
  final List<void Function(Event)> _observers;

  FilteredObservable(this._predicate, this._observers);

  void Function(Event) notify(Event event) {
    if (!_predicate(event)) return null;

    void Function(Event) last;
    for (var observer in _observers) {
      observer(event);
      last = observer;
    }

    return last;
  }
}
  1. 考慮對(duì)參數(shù)使用函數(shù)類型語(yǔ)法。
Iterable<T> where(bool Function(T) predicate) => ...
  1. 使用Object而不是dynamic進(jìn)行注釋植榕,以指示允許使用任何對(duì)象乳丰。
    使用dynamic會(huì)發(fā)送更復(fù)雜的信號(hào)。這可能意味著DART的類型系統(tǒng)不夠復(fù)雜内贮,無法表示所允許的一組類型产园,或者值來自互操作或靜態(tài)類型系統(tǒng)的權(quán)限之外,或者您明確希望在程序中的該點(diǎn)具有運(yùn)行時(shí)動(dòng)態(tài)性夜郁。
void log(Object object) {
  print(object.toString());
}

/// Returns a Boolean representation for [arg], which must
/// be a String or bool.
bool convertToBool(dynamic arg) {
  if (arg is bool) return arg;
  if (arg is String) return arg == 'true';
  throw ArgumentError('Cannot convert $arg to a bool.');
}
  1. 將Future<void>用作不生成值的異步成員的返回類型什燕。
  2. 避免使用FutureOr<T>作為返回類型。
    如果一個(gè)方法接收FutureOr<int>作為參數(shù)竞端,意味著使用時(shí)可以傳參為int或Future<int>屎即。所以如果你的返回類型FutureOr<int>,則使用方還需要判斷是int還是Future<int>
Future<int> triple(FutureOr<int> value) async => (await value) * 3;//good
//bad
FutureOr<int> triple(FutureOr<int> value) {
  if (value is int) return value * 3;
  return (value as Future<int>).then((v) => v * 3);
}
//good
Stream<S> asyncMap<T, S>(
    Iterable<T> iterable, FutureOr<S> Function(T) callback) async* {
  for (var element in iterable) {
    yield await callback(element);
  }
}

參數(shù)聲明規(guī)則

  1. 避免定位布爾參數(shù)。
//bad
new Task(true);
new Task(false);
new ListBox(false, true, true);
new Button(false);
//good,考慮使用命名的參數(shù)技俐,增加構(gòu)造函數(shù)乘陪,或使用常量
Task.oneShot();
Task.repeating();
ListBox(scroll: true, showScrollbars: true);
Button(ButtonState.enabled);
//good
listBox.canScroll = true;
button.isEnabled = false;
  1. 如果用戶可能希望省略前面的參數(shù),請(qǐng)避免使用可選的位置參數(shù)雕擂。
String.fromCharCodes(Iterable<int> charCodes, [int start = 0, int end]);

DateTime(int year,
    [int month = 1,
    int day = 1,
    int hour = 0,
    int minute = 0,
    int second = 0,
    int millisecond = 0,
    int microsecond = 0]);

Duration(
    {int days = 0,
    int hours = 0,
    int minutes = 0,
    int seconds = 0,
    int milliseconds = 0,
    int microseconds = 0});
  1. 避免使用接受特殊“無參數(shù)”值的強(qiáng)制參數(shù)啡邑。
var rest = string.substring(start);//good
var rest = string.substring(start, null);//bad
  1. 使用inclusive start和exclusive end參數(shù)接受范圍。
[0, 1, 2, 3].sublist(1, 3) // [1, 2]
'abcd'.substring(1, 3) // 'bc'

Equality

  1. DO override hashCode if you override ==.
  2. 一定要使==運(yùn)算符遵守相應(yīng)的數(shù)學(xué)規(guī)則井赌。
Reflexive: a == a should always return true.

Symmetric: a == b should return the same thing as b == a.

Transitive: If a == b and b == c both return true, then a == c should too.
  1. 避免為可變類定義自定義相等谤逼。
  2. 不要在custom的==運(yùn)算符中檢查空值。
    The language specifies that this check is done automatically and your == method is called only if the right-hand side is not null.
//good
class Person {
  final String name;
  // ···
  bool operator ==(other) => other is Person && name == other.name;

  int get hashCode => name.hashCode;
}
//bad
class Person {
  final String name;
  // ···
  bool operator ==(other) => other != null && ...
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仇穗,一起剝皮案震驚了整個(gè)濱河市流部,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纹坐,老刑警劉巖枝冀,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異耘子,居然都是意外死亡宾茂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門拴还,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人欧聘,你說我怎么就攤上這事片林。” “怎么了怀骤?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵费封,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蒋伦,道長(zhǎng)弓摘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任痕届,我火速辦了婚禮韧献,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘研叫。我一直安慰自己锤窑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布嚷炉。 她就那樣靜靜地躺著渊啰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绘证,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天隧膏,我揣著相機(jī)與錄音,去河邊找鬼嚷那。 笑死胞枕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的车酣。 我是一名探鬼主播曲稼,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼湖员!你這毒婦竟也來了贫悄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤娘摔,失蹤者是張志新(化名)和其女友劉穎窄坦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凳寺,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸭津,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肠缨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逆趋。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖晒奕,靈堂內(nèi)的尸體忽然破棺而出闻书,到底是詐尸還是另有隱情,我是刑警寧澤脑慧,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布魄眉,位于F島的核電站,受9級(jí)特大地震影響闷袒,放射性物質(zhì)發(fā)生泄漏坑律。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一囊骤、第九天 我趴在偏房一處隱蔽的房頂上張望晃择。 院中可真熱鬧,春花似錦也物、人聲如沸藕各。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)激况。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乌逐,已是汗流浹背竭讳。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浙踢,地道東北人绢慢。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洛波,于是被迫代替她去往敵國(guó)和親胰舆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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

  • 一個(gè)基本的Dart程序 下面的代碼中使用了很多Dart最基本的特性: 重要概念 所有你能夠賦值給一個(gè)變量的都是一個(gè)...
    YZune閱讀 14,508評(píng)論 2 14
  • 變量 創(chuàng)建變量并初始化變量:var name = 'Bob' ; 如果對(duì)象不限于單一類型:dynamic name...
    _白羊閱讀 238評(píng)論 0 0
  • Built-in types(內(nèi)置的類型) Dart 內(nèi)置支持下面這些類型: numbers strings bo...
    Love零O閱讀 592評(píng)論 0 4
  • 布爾值判斷:只有 true 對(duì)象才被認(rèn)為是 true蹬挤,其他:實(shí)例對(duì)象缚窿,null,false 都判斷為false 創(chuàng)...
    KtYY閱讀 474評(píng)論 0 1
  • 要多平庸就有多平庸。 你認(rèn)為你是個(gè)普通平凡的人吨悍,最后才會(huì)知道原來你可以更是個(gè)普通平凡的人扫茅。 總想站到高處,感受高處...
    賀嘉禾閱讀 667評(píng)論 2 3