Flutter 之 Dart語言基礎詳解 上篇

        通過了一個星期的React Native的學習和了解,感受仍是Flutter的優點會更高一些,並且從學習成原本說感受作安卓的同窗學習flutter會相對低一點,門檻會低不少。express

        固然dart的基礎筆者仍是從其餘朋友的資料總結而來,這裏我儘量的說的清楚一些!api

首先是關鍵字(56個)

 

關鍵字 - - -
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中的關鍵字仍是有不少同樣的,含義也是如此。數組

變量的聲明

  1. var
  2. dynamic
  3. Objec

首先聲明一個變量,變量的類型能夠改變:

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 和 Object 聲明的變量初始化後,變量的類型仍可改變:

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

final 和 const

這兩個關鍵字很重要

首先被這兩個關鍵字修飾的變量,變量類型是能夠省略的:

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。

內置類型

Number數值(num,int,double)

首先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 字符串

說道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 = ""]);

方法點進去能夠看到聲明的時候咱們須要傳兩個參數,集合、切割符號,這正如輸出的結果咱們看到確實如此!

Booleans 布爾值 (bool)

bool的運用很簡單,跟Java是同樣的:

bool isNull;
print('isNull:${isNull}');

運行結果:

你們確定知道了,由於isNull沒有初始化因此默認值確定是null,那若是咱們初始化以後輸出就會以下:

isNull:false or isNull:true

List 列表(數組 List)

//聲明一個自動長度的數組
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很相似,方法名都是顧名思義,很容易理解,這裏就不一一列舉了!

Maps 鍵值對集合 (Map)

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 集合 (Set)

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 符號字符

//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);

上篇就到這裏,下篇待續……

相關文章
相關標籤/搜索