通過了一個星期的React Native的學習和了解,感受仍是Flutter的優點會更高一些,並且從學習成原本說感受作安卓的同窗學習flutter會相對低一點,門檻會低不少。express
固然dart的基礎筆者仍是從其餘朋友的資料總結而來,這裏我儘量的說的清楚一些!api
關鍵字 | - | - | - |
abstract | do | import | super |
as | dynamic | in | switch |
assert | else | interface | sync* |
enum | implements | is | this |
async* | export | library | throw |
await | external | mixin | true |
break | extends | new | try |
case | factory | null | typedef |
catch | false | operator | var |
class | final | part | void |
const | finally | rethrow | while |
continue | for | return | with |
covariant | get | set | yield* |
default | if | static | deferred |
從上面的關鍵字裏面能夠看出和Java中的關鍵字仍是有不少同樣的,含義也是如此。數組
var name; name = 'tom'; name = 123;
dynamic name; name = 'tom'; name = 123;
Object name; name = 'tom'; name = 123;
這裏是不會報錯的,說明變量的類型是能夠改變的,而且都是能夠print出來。async
var name = 'tom'; name = 123;//這裏是不對的,編譯器會報錯
這裏聲明一個name被發現時String類型的以後,就不能轉變其餘的類型了。ide
可是:函數
dynamic name = 'tom'; name = 123;
Object name = 'tom'; name = 123;
這裏dynamic和Object聲明的類型是能夠改變的。學習
String name = 'tom'; name = 123;//這裏已經定義name是Stiing類型的,就不能更改成int類型
看到這裏咱們想了解了,若是聲明一個變量,沒有初始值的時候他的默認值是什麼呢?this
dart裏面的默認值都是null,一切皆對象,對象的默認值是null。編碼
var name; assert(name == null); print("assert pass");//能夠正常打印
這裏咱們發現此處的斷言是能夠是真的,程序不會崩潰,說明默認值是null。spa
這兩個關鍵字很重要
首先被這兩個關鍵字修飾的變量,變量類型是能夠省略的:
const age = 1; final sex = '男';
被其修飾的變量沒法更改其值,而且聲明出來以後必需要進行初始化,相信學過Java的同窗確定對final這個關鍵字很熟悉了吧D)
var varList = const [1, 2, 3]; final finalList = const [1, 2, 3]; const constList = [1, 2, 3]; print([varList, finalList, constList]); varList = [1];//這裏容許更改 // constList = [1];//這裏不容許更改 // finalList = [1];
能夠更改非 final,非 const 變量的值,即便它曾經具備 const 值。
final List ls = [1, 2, 3]; ls[2] = 444; print(ls); const List cLs = [4, 5, 6]; cLs[1] = 4; print("\n"); print(cLs);
這裏一樣是更改集合中某個元素的數值,final的是沒有問題的,const的編譯時沒問題,可是運行起來會報錯:
Unsupported operation: Cannot modify an unmodifiable list
不能更改一個不能修改的集合。
final finalList1 = [1, 2, 3]; final finalList2 = [4, 5, 6]; print("\n"); print(identical(finalList1, finalList2)); //identical用於檢查兩個引用是否指向同一個對象 const constList1 = [1, 2]; const constList2 = [1, 2]; print("\n"); print(identical(constList1, constList2)); //identical用於檢查兩個引用是否指向同一個對象
這裏相同的集合final聲明的會在內存中重複建立,const聲明的就不會重複建立,上面打印:
external bool indentical(Object a, Object b);這個方法傳入兩個引用來檢測是否指向同一個對象,返回bool類型。
常量若是是類級別的,必需要使用 static const來修飾:
class C{ static const String a = 'hehe'; //這裏只有類級別的常量的時候咱們請使用static const來修飾,而且初始化 }
若是去掉static編譯就會報錯:Only static fields can be declared as const,只有靜態字段能夠聲明爲const。
首先int和double都是num的子類,用法跟int和double同樣,都是能夠直接進行運算:
num n1 = 1; num n2 = 1.0; print('n1 + n2 = ${n1+n2}');
輸出:
n1 + n2 = 2.0
自動識別double類型輸出2.0不會丟失精度。
轉換這個環節是必不可少的,在Java中咱們只int和double、float都是能夠進行和String互相轉換的,dart中也是能夠的:
int i2 = int.parse('1'); print('i2---->${i2}'); double d2 = 1;//當 double 的值爲 int 值時,int 自動轉爲 double print('d2:${d2}'); int i3 = int.tryParse('1.0');//返回 null print('i3:${i3}');
輸出以下:
這裏細心地同窗看到i3爲何輸出是null,而不是1或者1.0呢,咱們爲何調用tryParse而不用parse呢,試着去解析,若是有問題不會崩潰,我的理解這就是這個方法的真正的目的所在,1.0被識別出是double類型,咱們用int去解析而且接受就會致使丟失精度的問題因此不予經過,方法會返回null,可是咱們用parse來看看就發現程序崩潰了:
因此也就很容易理解了。
說道String,Java的同窗確定很熟悉啦,不過dart裏面的String是UTF-16編碼的,因此咱們能夠用單引號''或者雙引號「」來聲明字符串。
String string = 'haha'; String string1 = "hahaha";
都是ok的!
var name = 'HelloWorld'; //能夠在字符串中使用表達式: ${expression},若是表達式是一個標識符,能夠省略 {}。 //若是表達式的結果爲一個對象,則 Dart 會調用對象的 toString() 函數來獲取一個字符串 var names = 'HelloWorld ${name}'; //r 前綴能夠建立一個 「原始 raw」 字符串 //加了r,轉義符號 \n 換行 \t (按一次tab鍵的水平製表符)不起做用了 var rawNames = r"HelloWorld ${name}"; print('name:${names}'); print('rawNames :${rawNames}');
這裏咱們發現${}表達式能夠直接拿去變量值來進行輸出,而且在字符串前面加上r只有會發現這個表達式效果失效了,那這也是dart的一個規則吧,能夠試一下字符串裏面加上 \n、\t等轉義字符,會發現這些也都失效了,都被打印了出來!
看看下面代碼:
//可使用三個單引號或者雙引號也能夠 建立多行字符串對象 var multiLinesString = ''' Java Android Flutter'''; print('mutiLinesString:${multiLinesString}');
這裏咱們發現用了三個‘來聲明一個字符串,這樣得聲明有何意義呢?看一下效果:
大家會發現居然跟咱們擺放的字符串格式同樣,對的,他的含義就是這樣!
接下來看一下StringBuffer的使用:
/// StringBuffer var sb = StringBuffer(); //dart 2 能夠省略 new sb..write('aaa')..write('bbb')..write('ccc');//..級聯符實現鏈式調用 sb.writeAll(['aaa','bbb','ccc'],',');//第二個參數表示分隔符,將第一個參數列表裏的數據用這個分隔符拼接起來 print('sb:${sb}');
..的做用就是能夠實現鏈式調用,writeAll方法:
external void writeAll(Iterable objects, [String separator = ""]);
方法點進去能夠看到聲明的時候咱們須要傳兩個參數,集合、切割符號,這正如輸出的結果咱們看到確實如此!
bool的運用很簡單,跟Java是同樣的:
bool isNull; print('isNull:${isNull}');
運行結果:
你們確定知道了,由於isNull沒有初始化因此默認值確定是null,那若是咱們初始化以後輸出就會以下:
isNull:false or isNull:true
//聲明一個自動長度的數組 List growableList = new List(); growableList..add(1)..add(2)..add('HelloWorld'); print('growbleList: ${growableList}');
這裏咱們用到了new這個關鍵字進行List實例的建立,經過..符號進行鏈式操做添加集合數據,打印以下:
growbleList: [1, 2, HelloWorld]
也能夠換一種聲明方式:
var list = List(6); list[0] = "a"; list[1] = "b"; list[2] = "c"; list[3] = "d"; list[4] = "e"; list[5] = "f"; print('list:${list}');
這裏咱們聲明瞭一個固定長度的集合而且挨個添加數據,打印以下:
list:[a, b, c, d, e, f]
咱們還能夠固定元素:
var typeList = List<String>(); typeList..add("1")..add("2")..add("3"); print('typeList:${typeList}');
若是放入其餘的類型編譯器就會報錯。
還能夠這樣聲明:
var varList = [1, 2, 3];
List ls = [1, 2, 3];
都是能夠的。
還有List的一些經常使用方法,好比獲取第一個元素、最後一個元素等,還能夠直接增刪、添加集合addAll等方法跟Java很相似,方法名都是顧名思義,很容易理解,這裏就不一一列舉了!
Map的聲明有兩種方式:
一、直接聲明,用{}表示,裏面寫key和value,每組鍵值對中間用逗號隔開。
Map companys = {'Alibaba': '阿里巴巴', 'Tencent': '騰訊', 'baidu': '百度'}; // 輸出:{Alibaba: 阿里巴巴, Tencent: 騰訊, baidu: 百度} print(companys);
二、先聲明,再賦值
Map schoolsMap = new Map();//這裏用var聲明也是能夠的 schoolsMap['first'] = '清華'; schoolsMap['second'] = '北大'; schoolsMap['third'] = '復旦'; // 打印結果 {first: 清華, second: 北大, third: 復旦} print(schoolsMap);
看起來是否是也是很容易呢!
接下來看一下它的Api:
Map中的賦值能夠這樣作:
// Map的賦值,中括號中是Key,這裏可不是數組 aMap[1] = '小米';
相同的Key能夠覆蓋value數值,key是惟一的,value能夠時null也能夠是空‘’。
// 檢索Map是否含有某Key assert(aMap.containsKey(1));
//刪除某個鍵值對 aMap.remove(1);
能夠看出它的api也是很容易,相比Java有些地方我以爲方便很多呢!
注意事項:
// 注意事項 // 1.map的key類型不一致也不會報錯。 // 2.添加元素的時候,會按照你添加元素的順序逐個加入到map裏面,哪怕你的key, // 好比分別是 1,2,4,看起來有間隔,事實上添加到map的時候是{1:value,2:value,4:value} 這種形式。 // 3.map裏面的key不能相同。可是value能夠相同,value能夠爲空字符串或者爲null
set是無重複列表
看下面:
var dynamicSet = Set(); dynamicSet.add('a'); dynamicSet.add('b'); dynamicSet.add('c'); dynamicSet.add('1'); dynamicSet.add('1'); print('dynamicSet :${dynamicSet}');
這裏會輸出:
dynamicSet :{a, b, c, 1}
看到重複的不存在了!
set裏面有一個方法difference(),用來返回兩個set之間交集,好比,a.difference(b),則返回a有可是b沒有的,反之則反。
intersection這個方法是返回兩個集合的交集共有的;
union這個方法返回兩個集合的並集。
//Runes用於在字符串中表示Unicode字符 //https://copychar.cc/emoji/ String runesStr = '👄'; print(runesStr); print(runesStr.length); //表示佔 2 個 16 位字符 print(runesStr.runes.length); //表示佔 1 個 32 位字符 Runes runes = new Runes('\u{1f605} \u6211'); var str1 = String.fromCharCodes(runes); //使用String.fromCharCodes顯示字符圖形 print(str1); String str2 = '\u{1f605} \u6211'; //若是非4個數值,須要把編碼值放到大括號中 print(str2);
上篇就到這裏,下篇待續……