Flutter的優(yōu)勢以及Dart基礎(chǔ)語法

1.為什么要學習Flutter?

對于移動端開發(fā)人員來說,跨平臺技術(shù)一直是關(guān)注的重點,從H5,React Native到Flutter,我們似乎一直在尋找一種能“一套代碼洽损,多端運行”,同時還能有不俗的用戶體驗的技術(shù)。對于當前的大前端來說潮太,React Native的綜合成熟度和生態(tài)都要比Flutter好一些,對于中短期項目我們可能會選用前者,但是對于更長期的項目和發(fā)展來說铡买,F(xiàn)lutter是一種更徹底的解決方案更鲁,渲染能力和平臺一致性以及性能,它都具有更大的優(yōu)勢奇钞。

  • 我們從Web容器時代澡为,比如H5,Cordova,微信小程序,Ionic,這種基于web相關(guān)技術(shù)通過瀏覽器組件來實現(xiàn)界面及其功能景埃,在android上是WebView媒至,IOS上為UIWebView,這種采用原生內(nèi)嵌的瀏覽器來進行渲染谷徙,雖然可以做到多端一致拒啰,對于用戶體驗很是有限,尤其是一些復雜的UI邏輯完慧。

  • 對于泛Web容器時代來說谋旦,代表的技術(shù)有React Native和Weex∑妫基本上是完全放棄了瀏覽器控件的渲染蛤织,而是采用原生自帶UI組件實現(xiàn)代替了核心的渲染引擎,僅僅保持必要的基本控件渲染能力鸿染,簡化渲染指蚜,保證了良好的渲染性能。這個時代總體來說是做一個平衡涨椒,依然采用了前端友好的Js進行開發(fā)摊鸡,原生來接管繪制,依托于Js虛擬機的Js代碼提供所需的UI控件的實體蚕冬。

    但是對于這種映射來說免猾,在維護各個平臺的API升級方面往往需要巨大的成本,對于Android/Ios平臺上使用React Navie囤热,對開發(fā)人員的要求不僅僅是懂React那么簡單猎提,而是還需要懂兩個平臺的一些基礎(chǔ)開發(fā)知識。

  • 接下來是自繪引擎時代旁蔼,即從頭到尾寫一套跨平臺的UI框架锨苏,包括渲染邏輯甚至開發(fā)語言。所以對于移動端的開發(fā)人員來說棺聊,其實還是有一定的學習成本的(但對于已掌握一門編程語言的人幾乎可以忽略不計)伞租,但從平臺一致性,維護成本限佩,性能以及開發(fā)效率上都是全方位碾壓之前兩個時代的技術(shù)葵诈。

    1.Dart語言同時支持JIT和AOT裸弦。開發(fā)周期使用JIT,大大縮短開發(fā)周期作喘,調(diào)式模式支持有狀態(tài)的熱重載理疙;而發(fā)布期使用AOT,本地代碼的執(zhí)行更高效徊都,代碼性能和用戶體驗也更優(yōu)秀沪斟。Dart避免了搶占式調(diào)度和共享內(nèi)存,可以在沒有鎖的情況下進行對象分配和垃圾回收暇矫,在性能方面表現(xiàn)很是卓越主之。

    2.渲染引擎依靠跨平臺的Skia圖像繪制引擎,Skia將使用Dart構(gòu)建的抽象的視圖結(jié)構(gòu)結(jié)構(gòu)數(shù)據(jù)加工成GPU數(shù)據(jù)李根,然后數(shù)據(jù)通過OpenGL最終提供給GPU渲染槽奕,因為安卓上已經(jīng)有Skia引擎了,這也是Flutter Android SDK 要比 Flutter iOS SDK 小一些的原因房轿,打包后的apk也會比ipa小粤攒。

明白了為什么要學習Flutter,我們就更能堅定我們的腳步囱持,要學好Flutter夯接,就要先學習它的開發(fā)語言Dart,下面我們來看看Dart基礎(chǔ)語法:

2.Dart基礎(chǔ)語法

數(shù)據(jù)類型及其相關(guān)
含義 使用
int 整數(shù)纷妆,范圍為 -2^63 到 2^63 - 1. int x = 1;//沒有小數(shù)點就是int
double 浮點數(shù)盔几,64位(雙精度)浮點數(shù) double y = 1.1;//有小數(shù)點就是浮點數(shù)
num num 是數(shù)字類型,既可以表示整數(shù)掩幢,也可以表示浮點數(shù)逊拍,具體看賦的值 num x = 1;//num x是整數(shù) num y = 1.1;//num y是浮點數(shù)
String 字符串 Dart字符串采用UTF-16編碼 可以使用單引號或雙引號來創(chuàng)建字符串 var s1 = 'string'; var s2 = "string";字符串拼接采用“+”
bool 布爾值 var isTrue = true;
List List<E> E 表示 List 里的數(shù)據(jù)類型 用中括號來賦值 List<int> list = [1, 2, 3];
Set Set<E> E 表示 Set 里的數(shù)據(jù)類型 用大括號來賦值 Set<String> halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
Map Map<K, V> K 是 Key 的數(shù)據(jù)類型,V是 Value 的數(shù)據(jù)類型 Map<String,String> gifts = { // Key: Value 格式 'first': 'partridge', 'second': 'turtledoves', 'fifth': 'golden rings'};
Runes 表示采用 UTF-32 的字符串,用于顯示 Unicode 因為Dart字符串是UTF-16际邻,因此在Dart中表示32位的Unicode值需要Runes這個特殊語法芯丧。 Runes input = new Runes('\u{1f600}'); print(new String.fromCharCodes(input)); 打印出來是笑臉emoji:??
  • 在Dart中,所有類型都是對象類型世曾,都繼承自頂層類型Object缨恒,因此一切變量都是對象,數(shù)字轮听,布爾值骗露,函數(shù)和null都不能例外。

  • 未手動賦值的變量的值都是null蕊程,比如定義一個全局變量 int a,不進行手動賦值驼唱,打印出來a的值為null藻茂。

  • 默認定義的變量都是public的,加個“_”則為private,限制范圍并不是類訪問級別的,而是庫訪問級別辨赐。

  • 我們可以用var來聲明變量而不需要指定特別的數(shù)據(jù)類型优俘,但是一旦賦值后就不能改變數(shù)據(jù)類型的,而使用dynamic關(guān)鍵字就可以掀序。

    1.為什么var能定義所有變量帆焕?因為var 并不是直接存儲值,而是存儲的值的對象的引用不恭,例如:var content = 'Dart 語法' 這句叶雹,是名字為 content 的 var 變量存儲了值為 'Dart 語法' 的 String 對象的引用,所以 var 才能定義任何變量换吧。

    2.什么情況下用dynamic呢折晦?當這個變量沒法用 Dart 的類型來表示時,比如 Native 和 Flutter 交互沾瓦,從 Native 傳來的數(shù)據(jù)满着。所以你會看到 PlatformChannel 里有很多地方使用到了 dynamic。

  • final和Java中的final差不多贯莺,使用final和const的時候可以把var省略风喇,使用const的時候如果是類里的變量就必須加static,全局變量時不需要的缕探。在使用構(gòu)造器的時候也可以使用const變量魂莫,但是這個時候就不需要方法體了。const是編譯時常量撕蔼,在編譯時就進行初始化了豁鲤,但是final變量是當類創(chuàng)建的時候才初始化

函數(shù)
  • Dart不支持方法重載鲸沮,而是提供了可選命名參數(shù)和可選參數(shù):

    給參數(shù)增加{}琳骡,以 paramName: value 的方式指定調(diào)用參數(shù),也就是可選命名參數(shù)讼溺;

    給參數(shù)增加[]楣号,則意味著這些參數(shù)是可以忽略的,也就是可選參數(shù)怒坯。

//要達到可選命名參數(shù)的用法炫狱,那就在定義函數(shù)的時候給參數(shù)加上 {}
void test1Flags({bool bold, bool hidden}) => printTest("$bold , $hidden");

//定義可選命名參數(shù)時增加默認值
void test2Flags({bool bold = true, bool hidden = false}) => printTest("$bold ,$hidden");

//可忽略的參數(shù)在函數(shù)定義時用[]符號指定
void test3Flags(bool bold, [bool hidden]) => printTest("$bold ,$hidden");

//定義可忽略參數(shù)時增加默認值
void test4Flags(bool bold, [bool hidden = false]) => printTest("$bold ,$hidden");

//可選命名參數(shù)函數(shù)調(diào)用
test1Flags(bold: true, hidden: false); //true, false
test1Flags(bold: true); //true, null
test2Flags(bold: false); //false, false

//可忽略參數(shù)函數(shù)調(diào)用
test3Flags(true, false); //true, false
test3Flags(true,); //true, null
test4Flags(true); //true, false
test4Flags(true,true); // true, true

但是不可以同時把這符號同時放到同一個函數(shù)聲明下面,比如:

void testFun({int a},[int b]){} //錯誤的寫法
  • 對于只有一行的函數(shù)可以用 =>來進行簡寫
void main() => runApp(MyApp());
等價于
void main(){
    return runApp(MyApp());//runApp() 返回的是 void
}
  • Dart還提供了命名構(gòu)造函數(shù)的方式剔猿,使得類的實例化過程語義更加清晰视译。如下面實例,Point類中有兩個構(gòu)造函數(shù)归敬,TestA.bottom和TestA
class TestA {
  num x, y, z;
  
  TestA(this.x, this.y) : z = 0; // 初始化變量z
  TestA.bottom(num x) : this(x, 0); // 重定向構(gòu)造函數(shù)
  TestA.top():x=3; //重定向構(gòu)造器
  
  void printInfo() => print('($x,$y,$z)');
}

var p = TestA.bottom(100);
p.printInfo(); // 輸出(100,0,0)
var p = TestA.top();
p.printInfo(); // 輸出(3,0,0)

對于這種寫構(gòu)造器的方式酷含,和我們用Java自定義控件構(gòu)造器嵌套有著異曲同工之妙鄙早。

復用(extends,implement,mixin,on)

  • 在Dart中,你可以對同一個父類進行繼承或接口實現(xiàn)椅亚,但不可同時繼承和實現(xiàn)限番。
class TestA{
  num x,y,z;

  TestA(this.x,this.y):z =0;
  TestA.bottom(num x):this(x,0);
  TestA.top():x=3;
  
  void testCall() => print("($x=======,$y======)");

}

class TestB extends TestA{
  TestB(num x, num y) : super(x, y);
  
  @override
  void testCall() { //重寫testCall的實現(xiàn)
    // TODO: implement testCall
    super.testCall();
  }
}

class TestC implements TestA{
  @override
  num x;

  @override
  num y;

  @override
  num z;

  @override
  void testCall() {  //必須實現(xiàn)該方法
    // TODO: implement testCall
  }
}

可以看到,對于接口的實現(xiàn)方式呀舔,我們只是拿到了TestA的一個空殼子弥虐,不能復用原有的實現(xiàn),這個時候媚赖,我們可以用混入(Mixin)霜瘪,混入鼓勵代碼重用,可以視為具有實現(xiàn)方法的接口省古,不僅可以解決Dart缺少多重繼承的問題粥庄,同時也能避免多重繼承可能導致的歧義(菱形問題)。要使用混入豺妓,我們需要使用with關(guān)鍵字惜互,但是對于混入也有一定的要求,被混入的類不能有自己的構(gòu)造器琳拭,否則就會提示錯誤训堆。

class D{
  
  num x,y;
  D(this.x,this.y);
  void testCall() => print("($x=======,$y======)");
}

class E with D{  //編譯失敗,提示D類不能被混入白嘁,因為已經(jīng)定義了構(gòu)造器坑鱼。
  
}

至于為什么不能能用構(gòu)造器,我覺得Mixin目前的實現(xiàn)是以完全忽略構(gòu)造函數(shù)絮缅,忽略構(gòu)造函數(shù)調(diào)用鏈的方式實現(xiàn)的鲁沥,因此只支持隱式的構(gòu)造函數(shù)。一旦放開mixin的構(gòu)造函數(shù)支持耕魄,Dart勢必需要支持一套新的關(guān)鍵字語法画恰,來支持Mixin類繼承鏈上的構(gòu)造轉(zhuǎn)發(fā),代價太大吸奴。

  • mixin還可以和on進行配合使用**允扇,如果一個類mixin某個類,就必須先實現(xiàn)on的那個類则奥,詳情可以看看下面的代碼:
class F{

}

mixin G on F{

}

class H extends F with G{ //必須先繼承F類才可以考润,如果F是接口,那就必須先實現(xiàn)接口F

}
運算符

這里列出一些常用的表達读处,過于簡單的就不列出來了:

操作符 含義 例子
as 類型轉(zhuǎn)換 (emp as Person).firstName = 'Bob';<br />如果emp為null糊治,拋出異常
is 判斷是否是某個類型,如果是的話,就返回 true if (emp is Person) {
// 如果 emp 是 Person 類型
emp.firstName ='Bob';
}<br />如果emp 為null ,返回false
is! 判斷是否不是某個類型罚舱,如果不是的話井辜,就返回 true if (emp is! Person) {
// 如果 emp 不是 Person 類型
} <br /><br /如果emp 為null ,返回false
?. 類似于kotlin中的空安全揖赴,為空跳過下面的邏輯,避免拋出異常
??= 用默認值兜底的一種方式 a??=value抑胎,如果a為null,則給a賦值value渐北,否則跳過
?? 類似于三元表達式 a ?? b 類似于(a != null)? a : b
.. 級聯(lián)操作符阿逃,允許你對同一對象進行一系列的操作。 querySelector('#confirm') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'))
  • 運算符重載
    我們可以通過運算符重載來實現(xiàn)更復雜的功能
// 自定義相加運算符赃蛛,實現(xiàn)向量相加 
Vector operator +(Vector v) => Vector(x + v.x, y + v.y); 
// 覆寫相等運算符恃锉,判斷向量相等 
bool operator == (dynamic v) => x == v.x && y == v.y;

3.寫在最后

最近在研究Flutter,寫這篇文章也是做一個簡單的終結(jié)呕臂,希望更多的人加入Flutter的開發(fā)當中破托,最近開了一個淘寶店鋪,店鋪名字叫“程哥的日用百貨鋪”歧蒋,這里附上鏈接 https://shop105359436.taobao.com/?spm=a1z10.1-c-s.0.0.c1b42dd2nh1YwP 土砂,希望大家多多支持!

掘金鏈接:https://juejin.im/post/5e6ca09d6fb9a07c89151eda

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谜洽,一起剝皮案震驚了整個濱河市萝映,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌阐虚,老刑警劉巖序臂,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異实束,居然都是意外死亡奥秆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門咸灿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來构订,“玉大人,你說我怎么就攤上這事析显■暄剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵谷异,是天一觀的道長分尸。 經(jīng)常有香客問我,道長歹嘹,這世上最難降的妖魔是什么箩绍? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮尺上,結(jié)果婚禮上材蛛,老公的妹妹穿的比我還像新娘圆到。我一直安慰自己,他們只是感情好卑吭,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布芽淡。 她就那樣靜靜地躺著,像睡著了一般豆赏。 火紅的嫁衣襯著肌膚如雪挣菲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天掷邦,我揣著相機與錄音白胀,去河邊找鬼。 笑死抚岗,一個胖子當著我的面吹牛或杠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宣蔚,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼向抢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胚委?” 一聲冷哼從身側(cè)響起笋额,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎篷扩,沒想到半個月后兄猩,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡鉴未,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年枢冤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铜秆。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡淹真,死狀恐怖至非,靈堂內(nèi)的尸體忽然破棺而出亿鲜,到底是詐尸還是另有隱情,我是刑警寧澤尝江,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布啸驯,位于F島的核電站客扎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏罚斗。R本人自食惡果不足惜徙鱼,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧袱吆,春花似錦厌衙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蓬衡,卻和暖如春饲趋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撤蟆。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堂污,地道東北人家肯。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像盟猖,于是被迫代替她去往敵國和親讨衣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

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