Dart 語法學習筆記

變量

聲明變量幾種方式:

1. var name     = "Tim";   //自動推倒類型(infer)為string
2. String name  = "Tim";   //強類型定義
3. dynamic name = "Tim";   //可以修改變量類型 name = 4.0;
4. final name   = "Tim";   //首次使用時執(zhí)行一次
5. const name   = "Tim";   //類似全局常量或者static,編譯期間確定值

如果沒有賦初始值,默認變量初始值為null。

內(nèi)置類型

  1. Numbers: 編譯期間的數(shù)字類型的常量

    • int: 不大于64位,具體取決于平臺
    • double: 64位

    int 類實現(xiàn)了位移運算符;
    支持0x十六進制;
    浮點型支持科學計數(shù)法

  2. Strings: UTF-16 unicode 編碼

    語法跟python類似

    • &{express} 可以嵌入變量或者表達式
    • ''' ''' 或者 """ """,可以多行顯示
    • r'', raw字符串
    • In Dart, runes are the UTF-32 code points of a string.
  3. Booleans: 同樣是編譯期間常量。

    • bool 標識符,true & false
    • if (nonbooleanValue) 這樣比較是不行的,必須顯示的比較或者調(diào)用類isEmpty方法。
  4. Lists: 數(shù)組

    • 如果想要聲明一個編譯期常量的數(shù)組:var constantList = const [1, 2, 3]; //必須指定為const
  5. Maps: 字典 同js

  6. Runes: UTF-32 字符串。比如一些符號,表情等。\uXXXX

  7. Symbols: 不會用到。針對API推斷標識符有用。

函數(shù)

Dart是一個真正的面向?qū)ο缶幊陶Z言,一切都是對象,函數(shù)也是一個對象,它的類型是Function。

跟c語言函數(shù)語法一樣,但是可以省略返回值類型和參數(shù)類型。

也有自己的速寫語法:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
等價于
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

=> expr{ return expr; } 的簡寫。expr只能是一個語句,否則必須用{}方式。

一、參數(shù)

1. 函數(shù)調(diào)用時,可以使用 name:value方式制定參數(shù)。順序可以不是聲明順序。
2. @require 關(guān)鍵字,標示該參數(shù)必須傳入。
3. 可選參數(shù),使用[]擴起來。必須放到參數(shù)的最后位置,且不能存在多個[]的可選位置參數(shù)。
4. 參數(shù)可以設(shè)置默認值,如果沒有設(shè)置默認值,默認為null。

二、.. 操作符,可以看作是鏈式編程的語法。object.func1()..func2()..func3();
三、函數(shù)可以作為參數(shù)傳遞給函數(shù),作用同對象參數(shù)一樣。
四、匿名函數(shù)、lambda表達式、閉包。是一個概念。
五、返回值:所有函數(shù)都有一個返回值,默認返回return null;

運算符

很多操作跟c運算符一致,這里不做過多介紹。下面只介紹特殊運算符:

~/: 除法,返回整數(shù)

as: 類型判斷

is、is!: 類型檢測

..: 嚴格來說,double dot不是操作符,而是Dart的語法。對同一個對象做一系列操作,類似鏈式編程。

??=: 賦值,只有當左值為null的時候,才賦值。
// 只有當b是null的時候,給b賦值value; 否則b保持原值不變
b ??=: value;

??: 條件運算符,簡化if..else語句。expr1 ?? expr2,如果expr1不為null, 返回expr1; 否則返回expr2。

?.: 類似.操作符,獲取成員。問號的作用是標示對象可以是null

控制流

  • if..else: 條件必須是boolean類型
  • for:
    • 傳統(tǒng)for語法
    • for-in:可迭代的類或者類型才支持。例如:List, Set等
  • While and do-while
  • Break and continue
  • Switch and case: int和string都可以作為case條件;每個case后必須有break語句;不支持空case;
var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.

  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}
  • Assert

異常處理

  • Throw: 可以拋出非null的任何對象,包括exception和error對象。
  • Catch: 語法如下:on可以捕獲具體類型的exception;catch 可以跟on一起,也可以單獨使用。最多包含兩個參數(shù),e是拋出的異常,s是堆棧信息。
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}

try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}
  • rethrow: 再次拋出異常
void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // Runtime error
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // Allow callers to see the exception.
  }
}

void main() {
  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }
}
  • Finally: 捕獲異常后后會繼續(xù)執(zhí)行finally中的內(nèi)容。
try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}

  • 使用類成員: 使用.運算符引用對象成員和方法。
// If p is non-null, set its y value to 4.
p?.y = 4;
  • 使用構(gòu)造函數(shù): Dart 2中new操作符可選。構(gòu)造函數(shù)可以是類名,也可以是類名.標識符。
var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});
  • 獲取對象類型:使用runtimeType屬性。(Object對象定義,獲取運行時對象類型)

  • 成員變量
    沒有public、private、protected關(guān)鍵字。
    不需要設(shè)置成員變量默認值,不初始化的變量默認null。
    默認會對成員變量生成隱式的get和set方法。

  • 構(gòu)造函數(shù)
    構(gòu)造函數(shù)可以是跟類名一樣的名字,也可以聲明其他名字。

class Point {
  num x, y;

  Point(num x, num y) {
    // Use this only when there is a name conflict
    this.x = x;
    this.y = y;
  }
  
  // Syntactic sugar for setting x and y
  // before the constructor body runs.
  // Point(this.x, this.y); 等同于上面的構(gòu)造函數(shù),寫法更簡單
  
  // Named constructor:使用:Point p = Point.origin();
  Point.origin() {
    x = 0;
    y = 0;
  }
}

如果不寫構(gòu)造函數(shù),會默認生成一個構(gòu)造函數(shù);默認生成的構(gòu)造函數(shù)跟類同名,沒有參數(shù)。

構(gòu)造函數(shù)不能繼承。默認子類會調(diào)用基類的默認構(gòu)造函數(shù)或者無參數(shù)構(gòu)造函數(shù)。

跟C++一樣,Dart也有初始化列表(initializer list)。初始化列表要寫在調(diào)用基類構(gòu)造函數(shù)之前。

// Initializer list sets instance variables before
// the constructor body runs.
Point.fromJson(Map<String, num> json)
    : x = json['x'],
      y = json['y'] {
  print('In Point.fromJson(): ($x, $y)');
}

重定向構(gòu)造函數(shù):重定向構(gòu)造函數(shù)的函數(shù)體必須為空,通過冒號在后面定向到其他構(gòu)造函數(shù).

class Point {
  num x, y;

  // The main constructor for this class.
  Point(this.x, this.y);

  // Delegates to the main constructor.
  Point.alongXAxis(num x) : this(x, 0);
}

常量構(gòu)造函數(shù):可以創(chuàng)建一個編譯時的常量對象,對象構(gòu)造函數(shù)參數(shù)必須時常量。用于創(chuàng)建一個不變的對象(內(nèi)部成員不會改變)

class ImmutablePoint {
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);

  final num x, y;

  const ImmutablePoint(this.x, this.y);
}

工廠構(gòu)造函數(shù):不能直接使用this??梢詮腸ache獲取實例,也可能創(chuàng)建子類型的對象。

class Logger {
  final String name;
  bool mute = false;

  // _cache is library-private, thanks to
  // the _ in front of its name.
  static final Map<String, Logger> _cache =
      <String, Logger>{};

 //工廠構(gòu)造函數(shù)
  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);
  }
}
  • 成員函數(shù)
    getter和setter方法,是默認生成用于存取成員變量的成員函數(shù)。也可以顯式聲明(使用get和set關(guān)鍵字)
 class Rectangle {
 num left, top, width, height;

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

 // Define two calculated properties: right and 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;
 }

抽象方法:類似C++中的虛基類中的虛函數(shù),基類中沒有實現(xiàn),子類實現(xiàn)。

  • 抽象類:
    跟C++不同的是,可以通過工廠構(gòu)造函數(shù)(factory constructor)創(chuàng)建實例。

  • 隱含接口(Implicit interfaces):使用implements關(guān)鍵字,可以實現(xiàn)類的方法,可以實現(xiàn)多重繼承。

// A person. The implicit interface contains greet().
class Person {
  // In the interface, but visible only in this library.
  final _name;

  // Not in the interface, since this is a constructor.
  Person(this._name);

  // In the interface.
  String greet(String who) => 'Hello, $who. I am $_name.';
 }

// An implementation of the Person interface.
class Impostor implements Person {
  get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}

class Point implements Comparable, Location {...}
  • 擴展一個類
    關(guān)鍵字extends創(chuàng)建子類,使用super指向其基類。
    @override 關(guān)鍵字用來覆蓋基類的實現(xiàn)。
    covariant 關(guān)鍵字:表示收緊子類型

    class Animal {
    void chase(Animal x) { ... }
    }
    
    class Mouse extends Animal { ... }
      
    class Cat extends Animal {
      //只能傳Mouse和其子類
      void chase(covariant Mouse x) { ... }
    }
    

    不能訪問一個不存在的成員函數(shù),但是可以通過覆蓋noSuchMethod()方法,使代碼不拋出異常。

  • 枚舉類型:可以表示固定的常數(shù)的一種特殊的類。默認值index從0開始。

    enum Color { red, green, blue } //使用enum關(guān)鍵字定義枚舉
    
    assert(Color.red.index == 0);
    assert(Color.green.index == 1);
    assert(Color.blue.index == 2);
    

    枚舉類型使用的限制:

    1. 不能繼承,混合和實現(xiàn)一個枚舉。
    2. 不能顯式的實現(xiàn)一個枚舉類。
  • 向類中添加特性:使用mixins技術(shù)(類似多重繼承)
    關(guān)鍵字with

    class T = A with S;
    那我們得到的class T是怎么樣的呢?假設(shè)MA表示A中的所有方法,MS表示S中的所有方法,那么T中的方法集合為:MS U (MA - MS)。

    復(fù)雜一點的情況:class T = B with A, S; == class T = (B with A) with S;

  • 類成員和方法:同樣使用static關(guān)鍵字。

泛型

可以在運行時判斷泛型類型內(nèi)容的具體type。其他方面跟java或者c++差不多。

庫和可見性

  • 使用import導(dǎo)入要使用的庫。
  • 如果導(dǎo)入的多個庫中,有同名類或者函數(shù),可以通過別名區(qū)分。關(guān)鍵字as。類似c++中的namespace。
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

// Uses Element from lib1.
Element element1 = Element();

// Uses Element from lib2.
lib2.Element element2 = lib2.Element();
  • 也可以僅僅導(dǎo)入庫中的部分內(nèi)容 showhide關(guān)鍵字
// Import only foo.
import 'package:lib1/lib1.dart' show foo;

// Import all names EXCEPT foo.
import 'package:lib2/lib2.dart' hide foo;
  • 懶加載庫 deferred as關(guān)鍵字
import 'package:greetings/hello.dart' deferred as hello;

Future greet() async {
  await hello.loadLibrary();
  hello.printGreeting();
}
  • 如何實現(xiàn)庫。單獨章節(jié)進行講解。

異步支持

關(guān)鍵字asyncawait支持異步編程。

生成器

參考python中的生成器。
需要后續(xù)加強了解

可調(diào)用的類

Dart 語言中為了能夠讓類像函數(shù)一樣能夠被調(diào)用,可以實現(xiàn)call()方法。
具體使用的場景,需要調(diào)研

隔離

沙盒?

Typedefs

Dart中,函數(shù)也是對象。Function關(guān)鍵字,typedefs 可以給函數(shù)設(shè)置別名。

元數(shù)據(jù)

A metadata annotation begins with the character @, followed by either a reference to a compile-time constant (such as deprecated) or a call to a constant constructor.

Two annotations are available to all Dart code: @deprecated and @override.

注釋

  • 單行 //
  • 多行 /* */
  • 文檔注釋 /// 或者 /**
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,172評論 2 9
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,689評論 1 51
  • C++文件 例:從文件income. in中讀入收入直到文件結(jié)束,并將收入和稅金輸出到文件tax. out。 檢查...
    SeanC52111閱讀 3,112評論 0 3
  • 關(guān)鍵字:現(xiàn)金、現(xiàn)實 講兩件比較囧的事情。前提是:自從有了網(wǎng)絡(luò)支付之后,我很少帶現(xiàn)金在身上(經(jīng)常丟錢)。 四月份在成...
    之葤閱讀 102評論 0 0
  • 曾記何時?我已經(jīng)離開家鄉(xiāng)很多年了,遠方的你,現(xiàn)在還好嗎? 曾記何時?我們在一起暢談人生,暢想未來的時候,我們相擁而...
    簡得飛兔閱讀 784評論 0 13

友情鏈接更多精彩內(nèi)容