Flutter系列(1)--Dart語言介紹

衆所周知,Dart是Flutter官方指定語言。
是一種適用於萬維網的開放源代碼編程語言,由Google主導開發,於2011年10月公開。它的開發團隊由Google Chrome瀏覽器V8引擎團隊的領導者拉爾斯·巴克主持,目標在於成爲下一代結構化Web開發語言。摘自Wiki算法

先拋出一段Dart代碼:express

// Define a function.
printInteger(int aNumber) {
  print('The number is $aNumber.'); // Print to console.
}

// This is where the app starts executing.
main() {
  var number = 42; // Declare and initialize a variable.
  printInteger(number); // Call a function.
}
複製代碼
  • 其中包含了:
    // 註釋代碼
  • ... () {} 方法/函數定義
  • int 變量定義,內置變量類型,強類型方式定義
  • print 基礎代碼,用於輸出日誌
  • '' 字符串賦值
  • var{expression} 模板數據插入
  • main() 主入口函數
  • var 變量定義,不限定變量類型

一個很是好用的Dart代碼測試平臺:
DartPad編程

變量/常量

Dart中也區分變量(var)和常量(const),以及final定義的只能設置一次的變量。瀏覽器

Dart中,萬物皆爲Object,在後面文章中,必定要注意這一點,把這一點刻在內心。
內置類型: app

numbers

int:-2 to 2 - 1
int x = 1;
var x = 0xFFF;
var ps = int.parse('1') // var str = ps.toString()
複製代碼

double: IEEE 754標準
double y = 1.1;
var y = 2.3e10
var ps = double.parse('3.1415926') // var str = ps.toString() // var str = ps.toStringAsFixed(2)
複製代碼

Number類型的數值支持位運算(按位與/或/位移)less

var res = 2 << 1; // res is 4: 0010 << 1 = 0100 = 4
var res = 2 >> 1; // res is 1: 0010 >> 1 = 0001 = 1
var res = 3 | 8; // res is 11: 0011 | 1000 = 1011 = 11
var res = 3 & 8; // res is 0: 0011 & 1000 = 0000 = 0
複製代碼

strings

var s1 = 'string1'; // s1 = string1
var s2 = "string2"; // s2 = string2
var s3 = '${s1.toUpperCase()} $s2'; // s3 = STRING1 string2
複製代碼

booleans

var str = ''; var res = str.isEmpty; // result is true
var num = 0; var res = num < 0; //result is false
var tmp; var res = tmp == null; // result is true
var div = 0 / 0; var res = div.isNaN // result is true
複製代碼

lists

(also known as arrays)
List能夠指定聲明類型,也能夠不聲明類型,不聲明的話其中存儲的數值爲var異步

var list = [1, "1", true];
// or
List list = [1, "1", true];
// or
List<String> list = ["1", "1", "true"]; // 若是爲[1, "1", true]則會編譯報錯
// 另外一種類型聲明方式
List list = <String>[]

// 固然也可使用const來定義常量,會覆蓋var的可變性
var list = const [1,2,3];
list.add(5); // 由於定義的List爲const常量,因此沒法賦值,運行報錯


// 能夠利用循環拼接array
var list2 = [0, ...?list]; // list2 = [0, 1, "1", true]
// or
var list2 = [0, for(var i in list) '%i']; // list2 = [0, "1", "1", "true"]


// 可使用判斷語句
bool flag = true;
var list = [
  1,2,3,
  if (flag) 4
]; // res is 1,2,3,4

複製代碼

sets

Set:能夠認爲是去重的List,List是有序的,不惟一的,而Set是無序但惟一的。async

// Set
var country = {'China', 'USA', 'UK'}
// 類型聲明
Set<String> country = {'China', 'USA', 'UK'}
Set country = <String>{'China', 'USA', 'UK'}

// 枚舉
for(var i in country) {} // Set中,i爲值
// 也可使用forEach
country.forEach((val) {
  print('$val');
});
複製代碼

maps

Map:字典,由key value組成的數據,我的理解,List能夠簡單的理解爲key爲自增int的一個Map,一樣,Set能夠認爲是沒有Value只有Key的Map編程語言

// Map
var country = {
  1: 'China',
  2: 'USA'
}
// 類型聲明
Map<int, String> country = ...;
Map country = <int, String>{};

// 枚舉
for(var i in country.keys) {print(country[i]);} // Map中,i爲key
// 也可使用forEach
country.forEach((key, val) {
  print('$key: $val');
});
複製代碼

runes

(for expressing Unicode characters in a string)
Dart中的特殊符號使用Runes來表示,是UTF-32編碼的字符串。ide

var input = new Runes('\u2665');
var input = '\u{1f44f}';
複製代碼

symbols

// 待續

特性

在Dart中,不存在private/public/protect的定義方式
若是須要使用私有變量,則在變量前增長_便可,如mine爲公共變量,而 _mine爲私有變量

var/const/final的區別:

  • var爲變量,其值能夠在任意地方修改
  • const爲常量,其值在初始化後沒法修改
  • final爲變量,其值在第一次賦值後沒法修改

函數

定義

// 帶返回值的方法
bool isTest() {
	return _isTest;
}

// override方法
isTest() {
	return true;
}

// 方法也能夠簡寫
bool isTest() => a == b;

複製代碼

參數

Dart中的傳參有兩種形式,固定傳參和字典傳參

bool isSame(int a, [int b]) {return a == b;}
bool isSame({@required int a, int b = 0}) {return a == b;}

複製代碼

區別:

  • 固定傳參不能夠設默認值,字典傳參能夠設置默認值
  • 固定傳參中所定義的參數爲必傳,如需設置非必傳,可使用[]包裹,
    字典傳參爲選傳,如需必傳,則須要增長@required。
// 調用方式
// bool isSame(int a, [int b]) {return a == b;}
isSame(1, 2);

// bool isSame({@required int a, int b = 0}) {return a == b;}
isSame(b: 2, a: 1);

複製代碼
  • 方法嵌套與JavaScript一致

異步

首先咱們要清楚的一點是:
Dart是單線程模型,相似於JavaScript,不包含主線程與子線程之分

那麼,Dart中如何實現異步呢?
Dart中使用了EventLoop的方式來進行異步操做
EventLoop讀取EventQueue,並進行處理,直到EventQueue爲空
而新增異步代碼時,則添加至EventQueue中
異步操做包含用戶輸入,點擊,Timer,文件IO,以及本身實現的異步事件。

Event和MicroTask:
這兩個應該說是借鑑了JavaScript中異步的實現方案
微任務永遠優先於Event執行,相似於:
setTimeout()的方法會放在宏觀任務中,相似於EventQueue
而Promise這種則會放在微觀任務中,相似於MicroTask

異步任務調度

Dart中的異步任務可使用Future來插入EventQueue中
使用scheduleMicrotask函數來插入到MicrotaskQueue中
使用方法:

Future(() {
  // ...do sth
}).then((res) => {
  // ...do sth
}).then((res) => {
  // ...do sth
}).whenComplete(() => {
	// finally
});



async.scheduleMicrotask(() => {
	doTask()
});
void doTask() {
	// ...do sth
}
複製代碼

JIT/AOT

JIT(Just in time)爲實時編譯模式
AOT(Ahead of time)爲提早編譯模式
JIT通常在Debug中使用,用於實時調試與更新至最新代碼,但執行效率較低。
AOT通常用於發佈生產,編譯爲機器碼,執行效率高。

內存分配與垃圾回收

Dart的垃圾收集器是分代的,由兩個部分組成:新生代空間收集器、並行標記掃描收集器,還有一個重要的東西,就是調度器

  • 調度器
    在Flutter引擎中,爲了最小化垃圾收集對應用程序和UI性能的印象,與垃圾收集器提供了hook,當引擎檢測到應用程序處於空閒狀態(沒有與用戶交互)會發出警報,爲垃圾收集器提供運行其收集階段而不影響性能的機會。而且垃圾收集器能夠在這些空閒時間運行內存壓縮,從而較少內存碎片來優化內存
  • 新生代空間收集器
    此部分相似於Java的複製算法,用於清理壽命較短的對象,例如Stateless部件,雖然是會阻塞線程,但當與調度器結合使用,幾乎感知不到應用程序在運行期間的暫停,從本質上,新建的對象被分配給內存中的連續空間,在新建對象,會被分配到下一個可用空間,直到填充完分配的內存,但Dart使用的是一個凹凸的指針,因此這個過程很是快,分配新對象的空間由兩部分組成,任什麼時候候只用一半,當一半滿後,活動的對象將複製到另外一半空間中,一半就會所有清空,肯定對象是否活動,收集器以根對象開始,進行檢測他們引用的內容,這一部分相似於Java的可達性算法,有引用的對象將會被複制到另外一個空間中
  • 並行標記掃描收集器當對象達到必定的生命週期時,會被提上到另外一個新的內存空間,由另外一個收集器管理,此收集器有兩個階段:
    • 遍歷對象,標記仍在使用的對象
    • 掃描整個存儲器,並回收未標記的對象,而後清除全部標記
相關文章
相關標籤/搜索