dart 02函數

函數

  • Dart 是一門真正面向對象的語言, 甚至其中的函數也是對象,並且有它的類型 Funcation
  • 這也意味着函數可以被賦值給變量或者作爲參數傳遞給其他函數。 也可以把 Dart 類的實例當做方法來調用

main() 函數

任何應用都必須有一個頂級 main() 函數,作爲應用服務的入口。 main() 函數返回值爲空,參數爲一個可選的 List<String>

函數聲明

  • bool  isNoble(int number){a
    	// 函數體	
        return number>0;
    }
    // bool返回值 當返回值爲空可以寫void 或者省略不寫 若不爲空則需要指定返回類型 比如int string bool等 
    //isNoble 函數名稱
    //int 參數類型
    //number 參數 
    
  • 函數簡寫

    • 如果函數中只有一句表達式,可以使用簡寫語法:

      • bool isNoble(int number) =>number > 0;
        
      • => *expr* 語法是 { return *expr*; } 的簡寫。 => 符號 有時也被稱爲 箭頭 語法

    • 在箭頭 (=>) 和分號 (😉 之間只能使用一個 表達式 ,不能是 語句 。 例如:不能使用 if 語句 ,但是可以是用 條件表達式.

函數參數

dart 除了普通的參數之外還支持可選參數 以及設置可選參數默認值

dart 參數如果不指定參數類型 示例test(param)那麼param將是dynamic類型

可選參數

可選參數可以是命名參數或者位置參數,但一個參數只能選擇其中一種方式修飾

命名可選參數

  • 可選的命名參數調用函數時可以指定命名參數

  • 與順序無關 在調用函數的時候需要指明參數名 例如paramName:value

  • 定義函數參數時用{}包裹 例如{param1,param2...}

  • 可以指定參數類型 也可以不指定類型 例如{params,int param1}

  • 默認值舊版本用: 新版本支持= 推薦使用= 沒有賦值 值爲null 例如:{param1="nike",int param2}

  • @required 修飾的參數爲必傳參數

  • 示例

    • void enableFlags({bool param1, String param2 = '2', @required param3}) {
        if (param1) {
          print(param2 + param3.toString());
        }
      }
      
  • 調用

    • /*可選命名參數*/
        enableFlags(param1: true, param3: 3);
        enableFlags(param1: true, param2: 'test', param3: 3);
      

位置可選參數

  • 參數值依次賦值 與順序有關

  • 定義函數參數時用[]包裹

  • 同樣可以指定參數類型也可以不指定參數類型

  • 默認值用=沒有賦值 值爲null

  • 示例

    • void enableFlags2(bool param1, [String param2 = 'Test2', param3, param4]) {
        if (param1 is bool) {
          print(param2 + param3.toString() + param4.toString());
        }
      }
      
  • 調用

    • /*可選的位置參數*/
      enableFlags2(true, 'new', 3);
      enableFlags2(true, 'new', 3, 4);
      
參數默認值
  • 默認值用=沒有賦值 值爲null 上面解釋有

可選參數示例

可傳遞List map 作爲可選參數
const 表示編譯時常量 故名思意 只有編譯前可以改變值 編譯後無法改變

  • 函數

    • void doStuff(
          {List<int> list = const [1, 2, 3],
          Map<String, String> gifts = const {
            'first': 'paper',
            'secend': 'cotton',
            'third': 'leather'
          }}) {
        print('list: $list');
        print('gifts:$gifts');
      }
      
  • 調用方式

    • /*可傳遞List map*/
        List<int> list = [4, 5, 6];
        Map<String, String> map = {
          'one': 'param1',
          'two': 'param2',
          'three': 'param3'
        };
        doStuff(list: list, gifts: map);
      

函數一等公民

  • 函數也是對象 可以賦值給變量

    • var sayHelloN = (name) => 'hello $name';// 後面函數就是匿名函數
      
  • 可以將函數作爲別的函數的參數

    • void printElement(int element) {
        print(element);
      }
      var listN = ['apples', 'banners', 'orange'];
      listN.forEach(printElement(element));
      

匿名函數

沒有名字的函數就稱爲匿名函數,有時候也被稱爲 lambda 或者 closure

  • 匿名函數可以賦值到一個變量中

    • var sayHelloN = (name) => 'hello $name';// 後面函數就是匿名函數
      
  • 函數定義

    • 匿名函數和命名函數看起來類似— 在括號之間可以定義一些參數或可選參數,參數使用逗號分割。

    • //後面大括號中的代碼爲函數體:
      
      ([[Type] param1[, …]]) {
        codeBlock;
      };
      
  • 示例 定義一個五類型參數item的匿名函數,list每個元素調用該函數 打印元素位置和字符串

    • var listN = ['apples', 'banners', 'orange'];
        listN.forEach((item) {
          print('${listN.indexOf(item)}:$item');
        });
        listN.forEach((item) => print('${listN.indexOf(item)}:$item')); //用=>寫
      

函數閉包

  • 閉包 即一個函數對象。即使函數對象的調用在它原始作用域之外, 依然能夠訪問在它詞法作用域內的變量。

  • 函數可以風i定義到它作用域內的變量

    • 示例

    • makeAdder() 捕獲了變量 addBy。 無論在什麼時候執行返回函數,函數都會使用捕獲的 addBy 變量。

      • /// 返回一個函數,返回的函數參數與 [addBy] 相加。
        Function makeAdder(num addBy) {
          return (num i) => addBy + i;
        }
        
        void main() {
          // 創建一個加 2 的函數。
          var add2 = makeAdder(2);
        
          // 創建一個加 4 的函數。
          var add4 = makeAdder(4);
        
          assert(add2(3) == 5);
          assert(add4(3) == 7);
        }
        

函數返回值

所有函數都會返回一個值。 如果沒有明確指定返回值, 函數體會被隱式的添加 return null; 語句。

foo() {}

assert(foo() == null);

測試函數是否相等

//測試函數是否相等
//下面是頂級函數,靜態方法和示例方法相等性的測試示//例:

void foo() {} // 頂級函數

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

void main() {
  var x;

  // 比較頂級函數。
  x = foo;
  assert(foo == x);

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

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

  // 兩個閉包引用的同一實例(2號),
  // 所以它們相等。
  assert(y.baz == x);

  // 兩個閉包引用的非同一個實例,
  // 所以它們不相等。
  assert(v.baz != w.baz);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章