【轉(zhuǎn)】Flutter 基礎(chǔ)語(yǔ)法之Dart語(yǔ)法

針對(duì)當(dāng)下熱門的Flutter跨平臺(tái)開(kāi)發(fā)語(yǔ)言蔑滓,Dart語(yǔ)法是其根本末融,所以這里寫(xiě)了一篇關(guān)于Dart語(yǔ)法的文章尝胆,希望可以幫到各位快速入門Dart,覺(jué)得還不錯(cuò)的朋友麻煩動(dòng)動(dòng)手指頭給個(gè)star支持下礁阁,后續(xù)會(huì)出其他相關(guān)的開(kāi)發(fā)教程

Dart語(yǔ)法一天快速入門篇 (Github發(fā)布版本)

針對(duì)當(dāng)下熱門的Flutter跨平臺(tái)開(kāi)發(fā)語(yǔ)言巧号,Dart語(yǔ)法是其根本,所以這里寫(xiě)了一篇關(guān)于Dart語(yǔ)法的文章姥闭,希望可以幫到各位快速入門Dart裂逐,覺(jué)得還不錯(cuò)的朋友麻煩動(dòng)動(dòng)手指頭給個(gè)star支持下原創(chuàng)作教程,后續(xù)會(huì)出其他更多相關(guān)的開(kāi)發(fā)教程

環(huán)境安裝篇

Dart本地環(huán)境安裝(Mac)

如果本地還沒(méi)安裝homebrew的泣栈,需要先安裝: Homebrew 安裝地址

brew tap dart-lang/dart
brew install dart

升級(jí)版本 brew upgrade dart

vscode 需要安裝 Code runner 和 Dart 兩個(gè)插件

類型

Dart是強(qiáng)大的腳本類語(yǔ)言吕粗,可以不定義變量類型使用var字段(類似JavaScript)侥猩,系統(tǒng)會(huì)自動(dòng)推導(dǎo)該變量類型 好比 var str = 'hello world' 也可以用 String str = 'hello world' , var a = 1和 int a = 1

常量修飾符final和const

const表示值不變,并且一開(kāi)始就需要賦值 final也表示該值不能修改,但可以初始化不賦值檐什,但是只能賦值一次

示例代碼

final a = new DateTime.now(); print(a);
const b = new DateTime.now(); print(b);

數(shù)值類型 String bool List Map類型分析

  • String(定義) 可以用三個(gè)單引號(hào)或者雙引號(hào)务蝠,可以對(duì)字符串進(jìn)行換行調(diào)整诅需,輸出到控制臺(tái)還是會(huì)按照定義的方式輸出信殊,單引號(hào)或雙引號(hào)的不能這么輸出

  • String(輸出格式,例如str1= 'a', str2= 'b') 可以使用print('str1str2'); 輸出結(jié)果a b,另一種拼接方式,可以直接用+號(hào)伞广,例如 print(str1 + str2)

  • 數(shù)值類型包括int,double

  • bool取值true拣帽、false (1或者任何非null類型的都為true)

  • List,列表相對(duì)來(lái)說(shuō)是支持動(dòng)態(tài)操作的,增(add),刪(removeAt),改(list[0]=null)嚼锄,長(zhǎng)度(length屬性),插入(insert(index, element))

  • List支持定義泛型减拭,例如var list = new List<String>();

  • Map類型,可以直接用var定義区丑,同樣支持泛型定義拧粪, 例如var map = new Map<String, int>();

類型判斷 is 和 ?沧侥?= 和isEmpty

判斷是否是某個(gè)類型的值, xx is 類型名稱

??= 如果左邊的類型是null ,則將右邊的值賦值給左邊可霎, 好比 int a; a??=10; a的最終結(jié)果就是10

isEmpty判斷字符串是否為空串,如果判斷對(duì)象是null會(huì)報(bào)錯(cuò)宴杀,例 str.isEmpty(屬性不是方法)

類型轉(zhuǎn)換

  • Number轉(zhuǎn)String使用toString()
  • String轉(zhuǎn)Number使用 parse()

Dart常用屬性以及方法

屬性

  • length
  • reversed (倒序列表癣朗,輸出對(duì)象是元組)
  • isEmpty
  • isNotEmpty
  • keys 獲取所有的key值 (主要用在字典上)
  • values 獲取所有的value值(主要用在字典上)

方法

  • toList() 將list對(duì)象轉(zhuǎn)List
  • addAll() 拼接數(shù)組
  • indexOf() 查到返回索引值,查不到返回-1
  • removeAt() 刪除指定索引
  • join() 將列表以特定符號(hào)拼接成一個(gè)字符串
  • split() 將字符串以特定符號(hào)轉(zhuǎn)成list
  • containsValue() 是否包含某個(gè)值

循環(huán)方式

foreach

示例

  var list = ['1','2', '3'];
  var map = {'name':'zhangsan','age':10};

  list.forEach((value){
    print("value is $value");
  });

  map.forEach((key,value){
    print("key is $key , value is $value");
  });

map

說(shuō)明 :對(duì)list中的元素統(tǒng)一操作旺罢,例如統(tǒng)一加減乘除等

示例代碼

var li = [1, 3, 5];
var newLi = li.map((value){
  return value*2;
});
print(newLi);

where條件

示例代碼

var li = [1, 3, 5];
var newLi = li.where((value){
  return value >= 3;
});
print(newLi);

any條件

說(shuō)明:判斷是否對(duì)象當(dāng)中有某個(gè)條件成立即返回true旷余,好比列表中大于6的元素是否存在

示例代碼

var li = [1, 3, 5];
var flag = li.any((value){
  return value >=6;
});
print(flag);

函數(shù)

注意:函數(shù)的形參可以不指定類型盾致,返回值也是可以不指定的,但是為了規(guī)范寫(xiě)法荣暮,一般還是帶上特定的類型做修飾,例如無(wú)返回使用關(guān)鍵字 void罩驻,形參用強(qiáng)類型限定防止外部參數(shù)傳入任意類型導(dǎo)致出錯(cuò)穗酥。

  • 可選參數(shù) printInfo(String username, [int age]); 可選參數(shù)一般放最后

  • 默認(rèn)參數(shù) printInfo(String username, [sex='男']);

  • 將方法作為參數(shù)傳給函數(shù)(其實(shí)也類似與匿名函數(shù),參考代碼片段二)

代碼片段1


void fn(){
  print('fn invoke');
}

void fn2(fnName) {
  fnName();
}

main() {
  fn2(fn);
}

代碼片段2

var fn = (){
  print('hello world');
};

main() {
  fn();
}

  • 如果函數(shù)的方法體只有一句代碼惠遏,可以用=>代替花括號(hào),以下例子用forEach砾跃,例如:
main() { 
  var list = ['zhangsan', 'lisi', 'wangwu'];
  list.forEach((value)=>print(value));
}

自執(zhí)行函數(shù)

說(shuō)明:實(shí)際為匿名函數(shù)自己調(diào)用

  ((){
    print('123');
  })();

閉包

特點(diǎn):能使變量常住內(nèi)存并且不會(huì)污染全局,既有全局變量的特點(diǎn)也有局部變量的特點(diǎn)

main() {
  func(){
    int a=100;
    return (){
      a++;
      print(a++);
    };
  }

  var func2 = func();
  func2();
  func2();
  func2(); 
}

初始化聲明

可以在生成對(duì)象的同時(shí)初始化內(nèi)部參數(shù)节吮,如下代碼片段:


class Rect {
  int width;
  int height;

  //初始化參數(shù)
  Rect():width=10,height=10{}

  get area {
    return this.width * this.height;
  }

  set areaWidth(int width) {
    this.width  = width;
  }

}

main() {
  Rect rect = new Rect();
  print(rect.area);
}

Flutter中生成對(duì)象通常會(huì)省略new關(guān)鍵字抽高,如下代碼片段

var rect = Rect();

//類似flutter中返回widget
return Center();//此處省略了new關(guān)鍵字

默認(rèn)構(gòu)造函數(shù)

默認(rèn)構(gòu)造函數(shù)跟類名一致,如下代碼片段:

class Person{
  String name;
  int age;

  //默認(rèn)構(gòu)造函數(shù)(只能存在一個(gè)默認(rèn)構(gòu)造函數(shù))
  Person(String name, int age) {
    this.name = name;
    this.age  = age;
  }
}

以上代碼可以簡(jiǎn)寫(xiě)為如下:

class Person{
  String name;
  int age;

  //默認(rèn)構(gòu)造函數(shù)(只能存在一個(gè)默認(rèn)構(gòu)造函數(shù))
  // Person(String name, int age) {
  //   this.name = name;
  //   this.age  = age;
  // }

  //默認(rèn)構(gòu)造函數(shù)簡(jiǎn)寫(xiě)
  Person(this.name, this.age);
}

命名構(gòu)造函數(shù)

一個(gè)類寫(xiě)多個(gè)命名構(gòu)造函數(shù)透绩,寫(xiě)法如下:

class Person{
  String name;
  int age;

  Person.now(String name, int  age) {
    this.name = name;
    this.age  = age;
  }

  Person.now2(String name, int  age) {
    this.name = name;
    this.age  = age;
  }
}

main() {
  Person p = new Person.now('zhangsan', 10);
  Person p2 = new  Person.now2('lisi', 11);
}

類內(nèi)部的函數(shù)中訪問(wèn)類屬性

class Person{
  String name;
  int age;

  void printInfo(){
    //通過(guò)${this.xxx}
    print('${this.name} , ${this.age}');

    //通過(guò)this.xxx
    print(this.name);

    //通過(guò)$name
    print('$name');
  }
}

對(duì)象操作符

  • 翘骂?條件運(yùn)算符(如果為空,后續(xù)操作不執(zhí)行帚豪,例如p為null碳竟,調(diào)用getInfo方法,政策執(zhí)行會(huì)報(bào)錯(cuò)狸臣,如果加上p?.getInfo()就不會(huì)調(diào)用了),示例代碼如下:
var p;

//這里調(diào)用報(bào)錯(cuò)莹桅,因?yàn)閜為null
p.getInfo();

//進(jìn)行非空判斷,不會(huì)執(zhí)行g(shù)etInfo方法 
p?.getInfo();

  • as 類型轉(zhuǎn)換

示例代碼

class Person {
  Person(){}

  void printInfo(){
    print("person test");
  }
}

main(){
  var p;
  p = '';
  p = new Person();

  (p as Person).printInfo();

}

  • is 類型判斷(參考以上【類型】章節(jié)的講解第三點(diǎn))

  • .. 級(jí)聯(lián)操作(連綴,這種語(yǔ)法類似于鏈?zhǔn)椒绞剑?/p>

class Person {
  String name;
  int age;
  Person(){}

  void printInfo(){
    print("person test");
  }
}

main(){
  Person p = new Person();
  p..name = 'zhangsan'
   ..age  =  10
   ..printInfo();
}

繼承

關(guān)鍵字extends

例如 class Teacher extends Person{} 表示Teacher類繼承自Person類

調(diào)用父類默認(rèn)的方法 super

class Teacher extends Person {
    //此方式調(diào)用父類的默認(rèn)構(gòu)造方法
    Teacher(String name, int age): super(name,  age);
}

重寫(xiě)父類方法 @override(可以不加,但是一般會(huì)加上)

 class Person {
  void printInfo(){
    print("person test");
  }
}

class Teacher extends Person{

  //采用關(guān)鍵字@override 標(biāo)記該方法是重寫(xiě)父類的烛亦,這點(diǎn)跟Java一樣
  @override
  void printInfo() {
    super.printInfo();
  }
}

抽象類

Dart中的抽象類主要用于定義標(biāo)準(zhǔn)诈泼,這個(gè)跟Java語(yǔ)言有點(diǎn)像,在Dart中煤禽,抽象類也可以作為抽象類接口來(lái)使用铐达, 抽象類通過(guò)關(guān)鍵字 abstract來(lái)定義,如果想作為接口來(lái)使用定義一套標(biāo)準(zhǔn)檬果,可以用關(guān)鍵字 implements來(lái)使用

抽象方法

  • Dart中娶桦,抽象方法不能用abstract來(lái)修飾,抽象類中沒(méi)有方法體的方法我們可以稱之為抽象方法
  • 如果子類繼承抽象的父類就必須實(shí)現(xiàn)里面的所有抽象方法(也可以說(shuō)是重寫(xiě)所有父類抽象方法汁汗,這里記得是抽象方法衷畦,抽象類可以存在非抽象方法)
  • 如果把抽象類作為接口來(lái)使用,就必須實(shí)現(xiàn)所有抽象類里面定義的所有屬性與方法
  • 抽象類不能直接被實(shí)例化知牌,只要子類才可以
  • 接口更多用于約束和規(guī)范祈争,而抽象類更多用于共用某些方法

示例代碼

//抽象類 繼承的子類必須實(shí)現(xiàn)抽象方法
abstract class A {
  printA();

  printAA(){
    print("AA");
  }
}

//接口 實(shí)現(xiàn)該接口必須實(shí)現(xiàn) 方法+屬性
abstract class B {
  String name;
  printB();
}

class C extends A implements B {
  @override
  String name;

  @override
  printA() {
    print('A');
  }

  @override
  printB() {
    print('B');
  }
}

mixins

Dart中有一種方式能實(shí)現(xiàn)類似多繼承,但實(shí)際不是繼承,用關(guān)鍵字with

示例代碼

class A {
  void printA(){

  }

  void getStr(){
    print("this is A method");
  }
}

class B {
  void printB(){

  }

  void getStr(){
    print("this is B method");
  }
}

class C with A, B {
  @override
  void printA() {
    print("重寫(xiě)的A方法");
  }

  @override
  void printB() {
    print("重寫(xiě)的B方法");
  }
}

void main() {
  C c = new C();
  c.printA();
  c.printB();

  //A和B均有g(shù)etStr 方法角寸,調(diào)用哪個(gè)方法取決于with之后寫(xiě)的順序有關(guān)菩混,最后一個(gè)會(huì)覆蓋前面所有的
  c.getStr();  

  print(c is A);  //true 
  print(c is B);  //true
}

訪問(wèn)修飾符

私有屬性和方法

Dart中沒(méi)有像Java語(yǔ)言中有public忿墅,private,protected這些訪問(wèn)修飾符沮峡,但是我們可以采用下劃線_ 把一個(gè)屬性或者方法定義成私有的疚脐,這一點(diǎn)跟Python的語(yǔ)法很像,但是應(yīng)該注意的一點(diǎn)邢疙,當(dāng)把該聲明了私有方法或?qū)傩詥为?dú)抽離為一個(gè)文件時(shí)棍弄,才生效,好比把Person類放在model目錄下疟游,然后其他文件引用了這個(gè)model呼畸,才變成不能訪問(wèn)的私有屬性和方法

getter和setter修飾符

以下是最原始的代碼片段:


class Rect {
  int width;
  int height;

  Rect(this.width,  this.height);

  // 簡(jiǎn)單地求面積
  int area() {
    return this.width * this.height;
  }

}

main() {
  Rect rect = new Rect(10, 2);
  print(rect.area());
}

get 關(guān)鍵字修飾


class Rect {
  int width;
  int height;

  Rect(this.width,  this.height);

  // 簡(jiǎn)單地求面積 通過(guò)添加get修飾符,可以把a(bǔ)rea函數(shù)變?yōu)閷傩缘脑L問(wèn)方式
  get area {
    return this.width * this.height;
  }

}

main() {
  Rect rect = new Rect(10, 2);

  //這里通過(guò)屬性的訪問(wèn)方式調(diào)用方法 
  print(rect.area);
}

set 關(guān)鍵字修飾


class Rect {
  int width;
  int height;

  Rect(this.width,  this.height);

  // 簡(jiǎn)單地求面積 通過(guò)添加get修飾符颁虐,可以把a(bǔ)rea函數(shù)變?yōu)閷傩缘脑L問(wèn)方式
  get area {
    return this.width * this.height;
  }

  set areaWidth(int width) {
    this.width  = width;
  }

}

main() {
  Rect rect = new Rect(10, 2);
  rect.areaWidth = 100;
  //這里通過(guò)屬性的訪問(wèn)方式調(diào)用方法 
  print(rect.area);
}

static

① 說(shuō)明: 通過(guò)static修飾的屬性和方法蛮原,外部可以通過(guò)類名直接調(diào)用,例如: Person.name Person.getInfo()

② static修飾的方法不能訪問(wèn)非static修飾的屬性

泛型

說(shuō)明:泛型是對(duì)類型的限定另绩,例如List這樣就只能傳入字符串類型的數(shù)據(jù)儒陨,List這樣只能傳入int類型的數(shù)據(jù)

示例代碼

main() {
  //可以用var也行
  List<String> list = new List<String>();
  list.add('hello');
  list.add('world');

  //以下這行代碼報(bào)錯(cuò)
  list.add(1);

  print(list);
}

Map類型指定泛型的如下

main() {
  var map = new Map<String, int>();
  map.addAll({'no':1});

  //以下這行代碼報(bào)錯(cuò)
  map.addAll({'username':'zhangsan'});

  print(map);
}

修飾方法

說(shuō)明:修飾方法可以不對(duì)類型進(jìn)行強(qiáng)制檢查,能提高函數(shù)的復(fù)用性

示例代碼


T returnValue<T>(T value) {
  return value;
}

main() {
  String name = returnValue('zhangsan');
  int age = returnValue(10);

  print('$name  $age');
}

自定義List泛型輸入


class JSList<T> {
  var list = new List<T>();

  add(T value) {
    this.list.add(value);
  }
}

main() {
  var list = JSList<String>();
  list.add('helloworld');

  //以下這行代碼報(bào)錯(cuò)笋籽,因?yàn)镴SList限定了輸入類型
  list.add(123);
}

泛型配合接口實(shí)現(xiàn)


abstract class A<T> {
  printInfo(T value);
}

class B<T> implements A<T> {
  @override
  printInfo(T value) {
    print('這是B的輸出類型');
  }
}

class C<T> implements A<T> {
  @override
  printInfo(T value) {
    print('這是C的輸出類型');
  }
}

main() {
  var b = new B<String>();
  var c = new C<int>();

  b.printInfo('hello world');
  c.printInfo(123);
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末框全,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子干签,更是在濱河造成了極大的恐慌津辩,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件容劳,死亡現(xiàn)場(chǎng)離奇詭異喘沿,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)竭贩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蚜印,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人留量,你說(shuō)我怎么就攤上這事窄赋。” “怎么了楼熄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵忆绰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我可岂,道長(zhǎng)错敢,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任缕粹,我火速辦了婚禮稚茅,結(jié)果婚禮上纸淮,老公的妹妹穿的比我還像新娘。我一直安慰自己亚享,他們只是感情好咽块,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著欺税,像睡著了一般侈沪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上魄衅,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音塘辅,去河邊找鬼晃虫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扣墩,可吹牛的內(nèi)容都是我干的哲银。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼呻惕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荆责!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起亚脆,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤做院,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后濒持,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體键耕,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年柑营,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屈雄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡官套,死狀恐怖酒奶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奶赔,我是刑警寧澤惋嚎,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站站刑,受9級(jí)特大地震影響瘸彤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜笛钝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一质况、第九天 我趴在偏房一處隱蔽的房頂上張望愕宋。 院中可真熱鬧,春花似錦结榄、人聲如沸中贝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邻寿。三九已至,卻和暖如春视哑,著一層夾襖步出監(jiān)牢的瞬間绣否,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工挡毅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒜撮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓跪呈,卻偏偏與公主長(zhǎng)得像段磨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耗绿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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