Dart學習筆記(二):方法

一、Dart方法

Dart是一種真正的面嚮對象語言,所以即使函數也是對象,具有類型和功能,意味着函數可以分配給變量或作爲參數傳遞給其他函數

String greet(String name) {
    return 'Hello, $name';
} 
  • 對於公開的API,推薦使用靜態類型,不過這不代表靜態類型是強制的,也可以不使用靜態類型,而使用自動類型推斷
greet(name) {
    return 'Hello, $name';
}

1. 箭頭語法

對於只包含一個表達式,可以簡寫爲:

bool greaterThanTen(n) => n > 10;

// 它相當於:
bool greaterThanTen(n) {
    return n > 10;
}

也就是說,·縮寫的語法=> expr相當於{ return expr; }·

說明

在箭頭(=>)和分號(;)之間只能出現一個表達式,不能使用語句(if、else、while之類),但是可以使用表達式與條件表達式

2、必選參數與可選參數

可選的命名參數

在定義函數時,使用{param1, param2,…}來指定命名參數:

void greet({ String action, String what }) {
    print('$action $what');
}


在調用函數時,可以使用paramName: value來指定命名參數

// 調用方法如下:
greet(what: 'Hello', action: 'say');

可選參數

可選參數需要將放置於[]中,如下:

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

// 調用方法如下:
say('Ruphi', 'hello'); // 輸出: Ruphi says Hello
say('Ruphi', 'hello', 'iPhone 8 Plus');
/*
輸出:
Ruphi says Hello
via iPhone 8 Plus
*/

默認參數

可以使用 = 來定義命名和位置參數的默認值。默認值必須是編譯時常量。如果沒有提供默認值,則默認值爲null。

void defaultArgs({ String from = 'Lili', String msg = 'Hello' }){
  print('$from says $msg');// 輸出:Lili says Hello
}

3. main() 函數

每個應用程序都必須有一個頂級的main()函數,它作爲應用程序的入口。main()函數返回void,並有一個可選的List參數作爲參數。

void main(List<String> args){
  print(args); //輸出:[]
  
}

4. 一等方法對象

  • 可以將函數作爲參數傳遞給另一個函數
void printElement(int element) {
  print(element);
}

void funAsArgs(){
  var list = [1, 2, 3];

// 將函數作爲變量傳入
  list.forEach(printElement);
}
  • 也可以賦值給一個變量
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');

5.匿名函數(lambda函數或者閉包函數)

匿名函數:沒有函數名稱的函數
匿名方法的語法如下:

([[Type] param1[, ...]]) {
    codeBlock;
};
···

可以爲變量分配一個匿名函數
```java
var list = ['apples', 'bananas', 'oranges'];
  /*list.forEach((item) {
    print('${list.indexOf(item)}: $item');
  });*/

  // 如果函數只包含一條語句,可以使用胖箭頭符號來縮短它
  // 等效於
  list.forEach(
      (item) => print('${list.indexOf(item)}: $item')
  );

6.詞法作用域(靜態作用域)

Dart變量的作用域在寫代碼的時候就已經確定了,因此,大括號裏定義的變量就只能在大括號裏訪問

bool topLevel = true;
void grammerScope(){
  var insideMain = true;

  void myFunction() {
    var insideFunction = true;

    void nestedFunction() {
      var insideNestedFunction = true;

      assert(topLevel);
      assert(insideMain);
      assert(insideFunction);
      assert(insideNestedFunction);
    }
  }
}

7.詞法閉包

一個閉包是一個方法對象,不論該對象在何處被調用,該對象都能訪問自己作用域內的變量(即捕獲了的變量),如下:

Function uid() {
  int id = 0;
  return () => id++;
}

void lexicalClosure() {
  var uidGenerator = uid();
  print(uidGenerator());
  print(uidGenerator());
  print(uidGenerator());
  /**輸出
   *  0
      1
      2
   */
}

8.判斷函數相等

foo() {}               // 頂級函數

class A {
  static void bar() {} // 靜態方法
  void baz() {}        // 實例方法
}

main() {
  var x;

  // 比較頂級方法
  x = foo;
  assert(foo == x); // 通過

  // 比較靜態方法
  x = A.bar;
  assert(A.bar == x); // 通過

  // 比較實例方法
  var v = new A(); // A的實例 #1
  var w = new A(); // A的實例 #2
  var y = w;
  x = w.baz;

  // 因爲 y.baz 和 x 都是指向實例#2的baz方法,因此它們是相等的
  assert(y.baz == x); // 通過

  // v.baz指向的是#1的baz方法,w.baz指向的是#2的baz方法,因此它們不相等
  assert(v.baz != w.baz); // 通過
}

9.返回值

所有函數都返回一個值。如果沒有指定返回值,則語句返回null;隱式附加到函數體。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章