Dart語(yǔ)法快速上手三《Dart2之方法》

這里開始講Dart語(yǔ)法中最重要的元素之一:方法,Dart里面的方法跟java還是有很大的不同

方法

Dart是一種真正的面向?qū)ο笳Z(yǔ)言,因此即使是函數(shù)也是對(duì)象并且具有類型Function。
這意味著函數(shù)可以分配給變量或作為參數(shù)傳遞給其他函數(shù)。
您也可以像調(diào)用函數(shù)一樣調(diào)用Dart類的實(shí)例。

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

這是一個(gè)標(biāo)準(zhǔn)的方法,其中返回類型是可以省略的,Dart會(huì)自動(dòng)推斷,而它下面的那個(gè)方法則是一個(gè)方法的簡(jiǎn)寫版

  • 可選參數(shù)和必選參數(shù)
    函數(shù)可以有兩種類型的參數(shù):必需和可選。首先列出所需參數(shù),然后列出任何可選參數(shù)。命名的可選參數(shù)也可以標(biāo)記為@required。當(dāng)我們調(diào)用一個(gè)方法的時(shí)候,我們可以給方法填上一個(gè)默認(rèn)值,例如:
//這是一個(gè)可選參數(shù)的的方法
  optionalFunction({int a = 1 ,int b =2}){
   return a+b;
 }

//在調(diào)用的時(shí)候我可以選擇傳一個(gè)參數(shù),也可以選擇不傳
main(){
optionalFunction(a:4);
optionalFunction(a:4,b:1);
optionalFunction(4,1);//TODO 錯(cuò)誤?。。?!
optionalFunction();
}

注意,這個(gè)方法在調(diào)用的時(shí)候不能像kotlin一樣通過(guò)參數(shù)的順序來(lái)指定參數(shù),可選參數(shù)的方法傳參必須在前面加上方法的參數(shù)名,來(lái)指定參數(shù)的值
如果我在可選參數(shù)前面加上@Required注解,就表明在這一群可選參數(shù)中,這個(gè)參數(shù)是必傳項(xiàng),不去傳遞這個(gè)參數(shù)是非法的

  optionalFunction({int a = 1 ,@required int b }){

   return a+b;

 }
optionalFunction(a:4);  //非法。必須傳遞b的值

注意:@Required 注解需要導(dǎo)入外部包才能使用
可以直接導(dǎo)入包:meta / meta.dart,也可以導(dǎo)入另一個(gè)導(dǎo)出meta的包,例如Flutter的包:flutter / material.dart。

  • 可選位置參數(shù)
    可選位置參數(shù)的意思就是即使你不傳入這個(gè)參數(shù),也可以調(diào)用這個(gè)方法,在上面一個(gè)例子中我們發(fā)現(xiàn)
  optionalFunction({int a = 1 ,int b =3 }){

   return a+b;

 }

這個(gè)方法,如果調(diào)用的時(shí)候是這樣調(diào)用的

optionalFunction(4);

這樣編譯是過(guò)不了的,系統(tǒng)不知道你這個(gè)4是a還是b
但是可選參數(shù)中這樣調(diào)用是可以的,即使你這個(gè)可選參數(shù)沒(méi)有默認(rèn)值,看代碼

String say(String from, String msg, [String device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

assert(say('Bob', 'Howdy') == 'Bob says Howdy');
assert(say('Bob', 'Howdy', 'smoke signal') ==
    'Bob says Howdy with a smoke signal');

在上面這個(gè)示例中,第三個(gè)參數(shù)device在第一次調(diào)用中是沒(méi)有傳遞的,但是編譯器沒(méi)有報(bào)錯(cuò),這就是可選位置參數(shù)與全部可選參數(shù)的區(qū)別

級(jí)聯(lián)表示法

級(jí)聯(lián)類似于java里面的build設(shè)計(jì)模式,可以通過(guò)單行一系列的語(yǔ)法操作一個(gè)對(duì)象

class Grammar2 {
  var x, y, z;
}
var g2 = Grammar2();
    g2 ..x = 1 ..y = 2..z=3;//這樣就完成了一系列的賦值
等價(jià)于
g2.x = 1; g2.y=2;g2.z=3;


  querySelector('#sample_text_id')
    ..text = 'Click me!'
    ..onClick.listen(reverseText);

Functions as first-class objects(這個(gè)感覺(jué)翻譯成中文怪怪的)

你可以傳遞一個(gè)方法當(dāng)作一個(gè)參數(shù)傳遞給另一個(gè)方法

void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

// Pass printElement as a parameter.
list.forEach(printElement);

上面這是一個(gè)簡(jiǎn)單版本的方法傳遞,這里延伸一下方法傳遞的概念Typedefs,java里面是沒(méi)有方法當(dāng)作參數(shù)的概念的,Dart將這個(gè)玩的很6,我們看看Typedefs

Typedefs

在Dart中,函數(shù)是對(duì)象,就像string和int一樣,typedef或?yàn)楹瘮?shù)類型提供了在聲明字段和返回類型時(shí)可以使用的名稱。當(dāng)函數(shù)類型分配給變量時(shí),typedef會(huì)保留類型信息。

class SortedCollection {
  Function compare;

  SortedCollection(int f(Object a, Object b)) {
    compare = f;
  }
}

// Initial, broken implementation.
int sort(Object a, Object b) => 0;

void main() {
  SortedCollection coll = SortedCollection(sort);

  // All we know is that compare is a function,
  // but what type of function?
  assert(coll.compare is Function);
}

上面這種是普通的方法傳遞的代碼,就跟注釋上面的疑問(wèn)一樣,都知道這個(gè)傳遞進(jìn)來(lái)的f是一個(gè)方法,但是是什么類型的方法呢?
這個(gè)時(shí)候typedef就派上用場(chǎng)了將f分配給比較時(shí),類型信息會(huì)丟失。f的類型是(Object,Object)→int(其中→表示返回),但比較的類型是Function。
如果我們將代碼更改為使用顯式名稱并保留類型信息,則開發(fā)人員和工具都可以使用該信息。

typedef Compare = int Function(Object a, Object b); //typedef關(guān)鍵字需要定義在class的外圍

class SortedCollection {
  Compare compare;

  SortedCollection(this.compare);
}

// Initial, broken implementation.
int sort(Object a, Object b) => 0;

void main() {
  SortedCollection coll = SortedCollection(sort);
  assert(coll.compare is Function);
  assert(coll.compare is Compare);
}

也可以增加泛型

typedef Compare<T> = int Function(T a, T b);

int sort(int a, int b) => a - b;

void main() {
  assert(sort is Compare<int>); // True!
}

方法的注解

Dart常用的有@override和@deprecated意思跟java一樣,這里略過(guò)

匿名方法

也稱作為無(wú)名方法,顧名思義,就是這個(gè)方法沒(méi)有方法名,其他的跟普通方法一樣。舉個(gè)例子:如果我們初始化一個(gè)值ax,這個(gè)ax的值需要從一個(gè)方法的返回值中拿到,在java里面我們這么做

int ax = getAx(9);
int getAx(int a){
  return a *2;
}

Dart中是這樣的
var ax = (a) => a2;
是不是簡(jiǎn)潔了很多?那么無(wú)名方法在哪里呢?就是這個(gè)(a)=>a
2這個(gè)方法除了沒(méi)有名字,其他跟上面的一樣
第二個(gè)應(yīng)用場(chǎng)景就是有些方法需要你傳遞一個(gè)方法進(jìn)去,第一種辦法是上面我們例子說(shuō)的,定義一個(gè)普通方法傳遞進(jìn)去

int sort(Object a, Object b) {
......
}
functionPass(sort);  //普通方法

//無(wú)名的寫法是這樣的

void functionPass((Object a, Object b){
.......
})

//更加常用的地方的是
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});

方法的返回值

這里單獨(dú)提一下方法的返回值,默認(rèn)情況下dart的方法不寫返回值不代表沒(méi)有返回值,他的返回值是null

foo() {}

assert(foo() == null);

未完待續(xù)~~~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容