本文首發於微信公衆號「劉望舒」html
Dart是Flutter SDK指定的語言,所以要學習Flutter,Dart是必須掌握的。關於Dart能夠寫一本書了,這裏用一篇文章來介紹下Dart的精髓,帶你快速入門。和Java語言相似的部分,這篇文章就儘可能再也不講了。前端
學習Dart語法最好須要用一個編輯器來實踐,這裏推薦使用IntelliJ IDEA。先下載Dart SDK,地址爲:www.gekorm.com/dart-window… 打開IntelliJ IDEA,菜單中點擊File-->Settings-->plugins,在plugins的搜索框中搜索Dart並安裝,而後重啓IntelliJ IDEA。 點擊File-->New Project-->Dart,按照下圖配置Dart SDK。 java
void main() {
print("Hello World");
}
複製代碼
點擊菜單的Run-->Run'main.dart'或者點擊工具條的運行圖標,就能在控制檯看到輸出的結果: 程序員
Dart是谷歌開發的計算機編程語言,亮相於2011年10月,最新的版本是Dart2。Dart誕生的緣由是谷歌的工程師出於對JavaScript的不滿,誕生的初期也贏得了部分前端開發者的青睞。可是這時JavaScript藉着NodeJS火了起來,在前端、後端、移動端無孔不入,Dart就漸漸被人遺忘了,可見Dart自己是具備很強的實力的,只是不大走運。谷歌並無放棄Dart,竭盡全力的推廣Dart:谷歌的Angular提供了Dart版本,指定Dart爲新系統Fuchsia的官方開發語言,Dart爲移動UI框架Flutter的開發語言,所以Dart又從新回到了人們的視野中。 Dart一般狀況下運行在DartVM上,可是在特定狀況下它也能夠編譯成本地代碼運行在硬件上,好比Flutter會將代碼編譯成指定平臺的本地代碼來提升性能。算法
Dart的特性主要有如下幾點:express
Dart的重要概念有如下幾點:編程
_
開始,那麼它和它的庫都是私有的。List<int>
(整數列表)或List<dynamic>
(任何類型的對象列表)。關鍵字 | |||
---|---|---|---|
abstract | dynamic | implements | show |
as | else | import | static |
assert | enum | in | super |
async | export | interface | switch |
await | extends | is | sync |
break | external | library | this |
case | factory | factory | factory |
catch | false | new | true |
class | class | null | try |
const | finally | on | typedef |
continue | for | operator | var |
covariant | Function | part | part |
default | get | rethrow | while |
deferred | hide | return | with |
do | if | set | set |
變量聲明使用var關鍵字,未初始化的變量的初始值爲null,即使是數字類型的變量也是null。json
var name = 'liuwangshu';
複製代碼
name變量的類型被推斷爲String,也能夠顯示聲明:windows
String name = 'liuwangshu' ;
複製代碼
若是對象不限於單一類型,能夠指定Object或dynamic類型。後端
Object name = 'liuwangshu' ;
複製代碼
若是定義的變量不會變化,可使用final或const來代替var,final變量只能設置一次。
final name = 'liuwangshu'
//name = 'zhangwuji' ; //會報錯
複製代碼
const變量爲編譯時常量,若是const變量在類級別,可使用static const。
const pi = 3.1415926;
const area = pi * 60 * 60;
複製代碼
const不只僅用來定義常量,也可使用const來建立常量的值。
var foo = const []; final bar = const []; const baz = [];//至關於`const []`
複製代碼
Dart的基本數據類型包括Number、String、Boolean、List、Set、Map、 Symbol、Runes。
number類型爲兩類:
Dart 字符串是 UTF-16 編碼的字符序列。 可使用單引號或者雙引號來建立字符串:
var s1 = '單引號適用於字符串文字';
var s2 = "雙引號一樣有效";
複製代碼
能夠在字符串中使用表達式,用法是: ${expression}
。若是表達式是一個標識符,能夠省略 {}。
var s = '乾坤大挪移';
assert('張無忌的$s' ==
'張無忌的乾坤大挪移');
複製代碼
使用三個單引號或者三個雙引號能夠建立多行字符串對象:
var s1 = '''
第一行
第二行
''';
var s2 = """第一行
第二行""";
複製代碼
Dart是強bool類型檢查,只有true對象才被認爲是true。
var name = '張無忌';
if (name) {
print('明教教主');
}
複製代碼
上面的代碼編譯不能經過,由於name是一個字符串,而不是bool類型。
下面是一個List 的示例:
var list = [1, 2, 3];
複製代碼
List的第一個元素的索引是0,最後一個元素的索引是 list.length - 1 。
var list = [1, 2, 3, 4, 5, 6];
print(list.length);
print(list[list.length-1]);
複製代碼
Dart中的Set是一組無序的集合。
var hero = ['張無忌', '風清揚', '張三丰', '獨孤求敗', '蕭峯'];
複製代碼
要建立一個空集,能夠在{}前面帶有類型參數:
var heros= <String> {};
複製代碼
使用add()或addAll()方法將條目添加到現有集中:
var heros = <String>{};
heros.add('石破天');
heros.addAll(hero);
複製代碼
Map是一個鍵值對相關的對象,鍵和值能夠是任何類型的對象,每一個鍵都是惟一的,而一個值則能夠出現屢次。
var player= {
// Keys Values
'20' : '斯諾',
'3': '艾弗森',
'40' : '希爾',
'8' : '麥基',
'55' : '穆託姆博'
};
複製代碼
使用Map構造函數也能夠實現一樣的功能:
var player = new Map();
player['20'] = '斯諾';
player['3'] = '艾弗森';
player['40'] = '希爾';
複製代碼
Dart是一個真正面向對象的語言,函數屬於Function對象。這意味着,函數能夠賦值給變量,也能夠當作其餘函數的參數。
void printName(String name) {
print('name is $name');
}
複製代碼
可選參數能夠是可選位置參數,也能夠是可選命名參數,但不能同時使用。
可選命名參數 調用方法的時候,可使用 paramName: value
的形式來指定參數的名稱,這樣就能夠根據paramName得知參數的含義,提升代碼的可讀性。
coffeeFlavor (sugar :true ,sugar :false );
複製代碼
定義函數時,使用{param1, param2, …}
的形式來指定命名參數:
coffeeFlavor ({bool sugar , bool sugar}) {
}
複製代碼
可選位置參數 把函數的參數放到 [] 中就變成可選位置參數了:
String go(String to, [String who]) {
var result = 'go to the $to';
if (who != null) {
result = '$result with $who';
}
return result;
}
複製代碼
可使用 =
來定義可選參數的默認值, 默認值必須是編譯時常量。 若是沒有提供默認值,則默認值爲 null。
String go(String to, [String who= 'liuwangshu']) {
var result = 'go to the $to';
if (who != null) {
result = '$result with $who';
}
return result;
}
String result= go ('beijing');
複製代碼
每一個應用都須要有個頂級的main() 函數來做爲入口才能執行。 main()函數的返回值爲 void 而且有個可選的 List<String>
參數。此前咱們舉的例子都是在main函數中運行才能得已驗證:
void main(){
void printName(String name) {
print('name is $name');
}
printName('liuwangshu');
}
複製代碼
大部分函數都有名字,例如 main() 或者 printElement()。 能夠建立沒有名字的匿名方法,格式以下所示。
([[Type] param1[, …]]) {
codeBlock;
};
複製代碼
下面的代碼定義了一個參數爲i(該參數沒有指定類型)的匿名函數。 list中的每一個元素都會調用這個函數打印出來.
var list = ['張無忌', '風清揚', '張三丰', '獨孤求敗', '蕭峯'];
list.forEach((i) {
print(list.indexOf(i).toString() + ': ' + i);
});
複製代碼
Dart的流程控制語句以下:
這些語句的大部分都和Java差很少,這裏主要講解for循環和switch語句。
標準的 for 循環:
var message = new StringBuffer("張無忌");
for (var i = 0; i < 3; i++) {
message.write('!');
}
複製代碼
List和Set等實現了Iterable接口的類還支持for-in
形式的遍歷:
var hero = ['張無忌', '風清揚', '張三丰', '獨孤求敗', '蕭峯'];
for (var h in hero) {
print(h);
}
複製代碼
Dart中Switch語句經過使用 == 來比較整型、字符串或者編譯時常量。被比較的對象必須都是同一個類的實例(不能是其子類),而且這個類不容許覆寫 ==。另外,枚舉類型很適用於在Switch語句使用。
String today='Friday';
switch(today){
case 'Monday':
print('星期一');
break;
case 'Friday':
print('星期五');
break;
}
複製代碼
捕獲異常能夠避免異常繼續傳遞。
try {
//...
} on OutOfLlamasException {
//...
} on Exception catch (e) {
print('Unknown exception: $e');
} catch (e) {
print('Something really unknown: $e');
}
複製代碼
使用on或者catch來聲明捕獲語句,也能夠同時使用。其中on來指定異常類型,catch來捕獲異常對象。 確保某些代碼無論有沒有出現異常都會執行,可使用finally語句來實現。
try {
//...
} catch(e) {
print('Error: $e');
} finally {
//...
}
複製代碼
Dart是一個面向對象編程語言,支持基於Mixin的繼承機制。Mixin能夠理解爲多繼承,在with關鍵字的後面爲一個或者多個類。
class Person{
run(){
print('跑');
}
}
class Wushu{
use(){
print('乾坤大挪移');
}
}
class Zhangwuji extends Person with Wushu{
int age;
Zhangwuji(int age){
this.age=age;
}
}
void main() {
var zhangwuji=new Zhangwuji(30);
zhangwuji.run();
zhangwuji.use();
}
複製代碼
經過如上代碼的驗證,Zhangwuji類擁有了Person和Wushu這兩個類的方法。
使用import來引入一個庫,對於Dart語言內置的庫,使用dart: scheme。 對於第三方的庫,可使用文件系統路徑或者 package: scheme。
import 'dart:io';
import 'package:mylib/mylib.dart';
import 'package:utils/utils.dart';
複製代碼
指定庫前綴 若是導入的兩個庫具備衝突的名字, 可使用庫的前綴來進行區分。 例如,若是library1和library2 都有一個名字爲Element的類,能夠這樣使用:
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// ...
Element element1 = new Element(); //使用lib1中的Element
lib2.Element element2 = new lib2.Element(); //使用lib2中的Element
複製代碼
導入庫的一部分 若是隻使用庫的一部分功能,則能夠選擇須要導入的部份內容。其中show表明只導入指定的部分,hide表明除了指定的部分都導入。
// 只導入foo
import 'package:lib1/lib1.dart' show foo;
// 除了foo,其餘部分都導入
import 'package:lib2/lib2.dart' hide foo;
複製代碼
延遲加載庫 延遲加載意味着應用程序能夠在須要的時候再加載庫,使用延遲加載庫的場景主要有如下幾點:
要延遲加載一個庫,須要先使用 eferred as來導入:
import 'package:deferred/hello.dart' deferred as hello;
複製代碼
當須要使用的時候,調用loadLibrary() 函數來加載庫:
greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
複製代碼
Dart庫中包含許多返回Future或Stream對象的函數。這些函數是異步的,它們在基本操做後會返回,而不等待該操做完成,例如讀取一個文件,在打開文件後就返回了。 雖然看起來有點像同步代碼,可是async和await的代碼是的確異步的。
await readFile() 複製代碼
要使用await,其方法必須帶有async關鍵字:
FileOperate() async {
var file= await readFile() //其餘處理 } 複製代碼
若是Dart中的類實現了call()函數,那麼這個類能夠當作方法來調用。
class JointFunction {
call(String a, String b, String c, String d) => '$a $b $c $d';
}
main() {
var jf = new JointFunction();
var out = jf("放","手","去","作");//1
print('$out');
}
複製代碼
在下面的示例中,JointFunction類定義了一個call()函數,它接收三個字符串並拼接它們。這樣在註釋1處就能夠調用JointFunction類了。
在Java中建立實例能夠用new,在Dart中你能夠選擇用new,也能夠選擇不用:
Element element = Element();
複製代碼
對於Android開發來講用new可能更習慣一些,可讀性也稍微好點,不用new的話顯得更簡潔,至於用不用new就看團隊的要求和我的的習慣吧,沒有絕對的好壞之分。
Flutter基礎系列
Flutter基礎(一)移動開發的跨平臺技術演進
Flutter基礎(二)Flutter開發環境搭建和Hello World
Flutter基礎(三)Dart快速入門
Flutter基礎(四)開發Flutter應用前須要掌握的Basic Widget
Flutter基礎(五)Material組件之MaterialApp、Scaffold、AppBar
Flutter基礎(六)Material組件之BottomNavigationBar、TabBar、Drawer
Flutter基礎(七)Scrolling Widget之ListView、GridView、PageView
Flutter基礎(八)手勢相關Widget:GestureDetector和Dismissible
Flutter基礎(九)資源和圖片
Flutter基礎(十)佈局Widget快速入門
Flutter基礎(十一)網絡請求(Dio)與JSON數據解析
Flutter基礎(十二)路由(頁面跳轉)與數據傳遞
Flutter基礎(十三)Flutter與Android的相互通訊
Dart的知識點有不少,這裏只介紹了一部分我認爲須要重點掌握的部分,若是想了解更多,能夠查看官方文檔,關於Dart的學習能夠結合Flutter邊寫邊學,不要只摳Dart的細節。
分享大前端、Android、Java等技術,助力5萬程序員成長進階。