筆者也是剛剛接觸dart的學習,畢竟作為一門出現比Java更晚的語言,感覺相比java還是有很多人性化的地方。現在就以和大家熟悉的java對比的角度,分享一下dart中和java不同的地方。
一、變數
我們知道在Java中宣告變數的時候一定要給予型別,但是在dart中可以不指定型別,進而使用Object、var、dynamic來代替,下面筆者帶大家一一過一下。
Object:其中Object代表所有物件,這個和java沒什麼區別,故而Object可以用來宣告所有型別的變數,當然也包括int。這裡需要注意的是,在dart中int也是一個類,而不是關鍵字了,可以在AS中點進去檢視int類資訊。進而我們get到dart並不是完全按照駝峰規則來編寫的,比如int是一個類,在駝峰規則中首字母本應該大寫,但是卻沒有。
var:其實在很多語言中都有var的用法,比如js、kotlin等。在dart中,var宣告的變數在宣告時已經決定了型別,後面不能更改,如果更改ide將會直接報錯。但是如果在宣告時沒有賦值,而是後面賦值的話,該變數型別是可以修改的。
dynamic:在執行時動態修改變數型別,可以隨意賦值任何型別。但是根據筆者經驗,一般執行時修改的效率都會更低一些,比如反射。所以不優先使用dynamic,後面碰到有坑再說。
final和const修飾符:使用final和const修飾符都可以將變數修飾成不可變,區別在於final是執行時賦值,但是const是在編譯時就已經賦值,所以如果將一個final變數賦值給const變數是會報錯的,因為const需要在編譯時給定值,但是此時final的變數並沒有真正賦值。反之const賦值給final則可以,const賦值給cost、final賦值給final均可以。
二、資料型別
在java中,擁有八大資料型別,相信大家都知道,這裡就不一一舉例了,在dart中那八大資料型別也是支援的,只是說從java中資料型別是關鍵字變成了類而已,並且取消了包裝類機制,和java使用起來一模一樣。值得一提的是,在dart中新增了一些資料型別,接下來一一說明。
num:前面說過,在dart中資料型別也是類,比如int雖然首字母小寫但是它依然是一個類。num也是一樣,num有2個子類,分別是int和double。需要注意的是在dart中沒有float這個資料型別,只有double。總結來說就是,如果一個數字既可能是整型又可能是浮點型的話,可以定義為num的物件。如果想讓double轉int可以使用doubleValue.toInt()方法,注意如果在計算時double/double表示返回一個double,但是使用double~/double來表示返回整數。
String:在dart中String可以用單引號、雙引號、三引號包起來,單雙引號作用類似,但是可以配合起來使用,解決在雙引號中包含特殊字元的問題,比如如果一個變數是a"b",如果在java中表示該字串,需要寫成"a\"b\"",但是利用單雙引號配合,則可以簡寫成'a"b"'或者"a'b'"即可。三引號代表可以換行的字串,可以直接在內容中間回車。
List:和java中的陣列類似,也可以初始化的時候直接賦值,比如List<int> lists = [1,2,3,3],下標也是從0開始,比如修改第一個元素的值為2可以寫成lists[0]=2。可以用const關鍵字來修飾,代表該list不可變。const List = XX和List = const XX這兩種寫法都可以。遍歷的話和java類似,也可以用for迴圈和foreach迴圈。for(int i in lists)、lists.foreach((e)=>{print(e)})。
map:在dart中map鍵值對支援在初始化的時候賦值,類似於這樣,map m ={ 'a': '阿里巴巴', 't': '騰訊', 'b': '百度'},獲取值也是根據key來獲取value,類似於var valuea = m['a']。遍歷的話仍然是迭代器,和java中一樣。
三、操作符
java中常見操作符在dart中依然可用,這裡說一說dart新增的操作符
1.型別判定操作符
as:類似於java中的強制轉換,將A型別的資料強制轉換成B型別,若無法轉換則丟擲異常
is:判斷某個物件是否屬於某個類,相當於java中的instanceof關鍵字
is!:和is相反,如果某個物件屬於某個類,則返回false
2.賦值操作符
??=:跟在一個變數後面,如果該變數值不為null則保持不變,如果為null則賦值成另外的值。舉個例子,b ??= value,如果b為null則不管,不為null則將b賦值成value
3.條件表示式
expr1 ?? expr2:如果expr1不為null,則返回其值,否則返回expr2的值
4.級聯操作符
..:級聯操作符可以在同一個物件上 連續呼叫多個函式以及訪問成員變數。 使用級聯操作符可以避免建立臨時變數, 並且寫出來的程式碼看起來更加流暢,相當於dart系統自帶build模式
5.安全操作符
?.:如果該操作符前面的變數為null則返回null不呼叫後面的方法或屬性,可以避免空指標。比如print(a?.length),如果不用安全操作符還需要判斷a是否為null,否則萬一為null會報空指標
四、方法
dart中方法也有很多有趣的地方,很多都是借鑑的其他語言優點。這裡就以java作為對比,列舉一下dart中新特性。
特性一 方式實現可簡寫
當方法中只有一個表示式時,可以不使用大括號包住實現,而是使用等號箭頭。注意,這裡的引數型別已經省略,返回值void其實也可省略,只是不推薦這麼做,省略號將變成dynamic。
特性二 一等方法物件
在dart中方法也是物件,方法的父類為Function類,這意味著方法可以賦值為變數,也意味著方法也可以作為引數傳遞其他方法中。
特性二 可選位置引數
把方法的引數放到[ ]中,代表引數可傳可不傳,傳值時按照引數位置順序傳遞 。如下定義了一個func方法,將i和j作為可選位置引數,最後呼叫時只傳了1個。根據可選位置引數的特性,當引數只傳了一個時,固定傳給第一個引數,最後打出的結果是i為1,j為null。注意,當傳的引數型別和方法第一個引數不一致時,比如講引數1換成字串,將直接報錯。
特性三 可選命名引數
把方法的引數放到{ }中,代表引數必須通過指定形參名進行傳參。如下圖,通過形參:值進行傳值,也可以只傳其中一部分,但是必須執行給誰傳值了。
特性四 預設引數值
使用[ ]或者{ }方式定義方法中的引數時,可以給定預設值。如下,在定義方法func時,我們給定了i和j分別一個預設值,在它們沒傳值時預設為0。
特性五 匿名方法
dart也支援匿名方法,也可以稱之為 lambda 或者 closure 閉包 ,可以作為傳參用。如下例,在呼叫方法時將一個匿名方法傳入另一方法test中,接下來在test方法呼叫引數f自身。
五、異常
和 Java 不同的是,所有的 Dart 異常是非檢查異常。 方法不一定宣告瞭他們所丟擲的異常, 並且不要求你捕獲任何異常。
另外,Dart 提供了 Exception
和Error
型別, 以及一些子型別。你還可以定義自己的異常型別。但是, Dart 程式碼可以丟擲任何非 null 物件為異常,不僅僅是實現了 Exception
或者Error
的物件。 如下圖,我們丟擲了一個整數異常,將在try...catch中的on int catch(e){}中被捕獲。這是和java不一樣的地方,java只能丟擲Exception子類。
在java中,通過catch到的Exception型別來區分Exception作相應處理。在dart中通過on 任意物件類的方式來抓住錯誤,該物件即為throw的物件,這裡可以使用rethrow將捕獲的異常重新丟擲。同時catch中引數e是丟擲的異常物件,可以通過e.runtimeType來檢視實際的類,s是錯誤堆疊。dart中try...catch也是有finally的,finally和Java一樣在try catch執行完後執行。
總結:本次以java作為對比,介紹了一下dart中的亮點新玩法,裡面肯定有沒有列全的,請大家多擔待,因為筆者也是剛接觸dart,後面有新的發現會繼續學習然後給大家分享。當然有很多方面沒有跟大家說到,沒說到的部分就預設和java一樣,大家可以自己嘗試去親身體驗一把。總而言之,我們可以發現,dart確實是一門很簡潔的語言,有很多地方都可以省略,比如變數型別、方法型別、單表示式的方法體括號等等。同時,又有很多的優化,只要在判空和賦值方面,具體見上面的操作符部分。然後,還有很多的新鮮玩法,比如支援匿名方法、可以將任何類作為異常捕獲物件、在java中熟知的int等基本資料型別也變成了類。我相信肯定還有更多的好玩點等著我們去學習發現,筆者後面學習到了再繼續分享出來。