Dart 要想飛的高基礎要打牢篇二(函數)

介紹

Dart 要想飛的高基礎要打牢篇一(變量與操做符)express

函數是可讀,可維護和可重用代碼的構建塊。 函數是一組用於執行特定任務的語句。 函數將程序組織成邏輯代碼塊。 一旦定義,能夠調用函數來訪問代碼。 這使得代碼能夠重用。 此外,函數能夠輕鬆讀取和維護程序的代碼。閉包

函數這塊的話沒啥好講的,我主要經過例子的方式來跟你們講解,相信你們看了就會明白,不明白的能夠直接留言,我會及時回覆的ide

函數

普通函數與 Lambda 函數的定義的方式函數

// 推薦
int add(int x, int y) {
    return x + y;
}

// 函數定義可省略類型,但並不推薦
add1(x, y) {
    return x + y;
}

// 當函數體內只有一個表達式的時候可使用:
//語法 [return_type]function_name(parameters)=>expression;
int add2(int x, int y) => x + y;

print(add(1, 2));
複製代碼

注意:全部的函數都返回一個值。若是沒有指定返回值,則 默認把語句 return null; 做爲函數的最後一個語句執行post

可選參數

可選命名參數:使用 {param1, param2, …} 的形式來指定命名參數ui

int add({int x, int y}) {
    x ??= 1;
    y ??= 2;
    return x + y;
}

print(add(x:2, y:4)); 	// 6
print(add()); 	 		// 3;
複製代碼

在這裏咱們在函數體內 x ??= 1 是由於這個函數是可選參數,若是沒有這個參數咱們直接 return x + y 會報錯的spa

提示很明確: 沒法讀取null的屬性,你們須要多多注意啊code

可選位置參數:把可選參數放到 [] 中,必填參數要放在可選參數前面cdn

int add(int x, [int y, int z]) {
	y ??= 2;
	z ??= 3;
	return x + y + z;
}

print(add(1));   		// 6
print(add(1, 3, 4));	// 8
複製代碼

可選命名參數默認值(默認值必須是編譯時常量), 目前可使用等號 '=' 或冒號 ':'對象

int add(int x, {int y = 2, int z = 3}) => x + y + z;

print(add(1));  		// 6
print(add(1, y: 5)); 	// 9
複製代碼

Dart SDK 1.21 以前只能用冒號,冒號的支持之後會移除,因此建議使用等號

可選位置參數默認值(默認值必須是編譯時常量),只能使用等號 '='

int add(int x, [int y = 2, int z = 3]) => x + y + z;

print(add(1));			// 6
print(add(1, 3, 5)); 	// 9
複製代碼

匿名函數

匿名函數的參照以下:

([[Type] param1[, …]]) {
	codeBlock;
};
複製代碼

匿名函數,顧名思義就是沒有名字的函數

無參匿名函數:

var info = () => print('這是無參匿名函數');
info();  // 這是無參數匿名函數
複製代碼

有參匿名函數:

var info = (name) => 'I am $name';
print(info('gaozan')); // I am gaozan
複製代碼

List.forEach() 就用的匿名函數

List list = [1, 2, 3];
list.forEach((item) => print('$item'));
複製代碼

一般不但願再次使用(即只使用一次的)的函數能夠定義爲匿名函數

擴展: 若是仍是想再次使用匿名函數的話, 也有方法, 像咱們上方的例子同樣。可賦值給變量,經過變量調用

閉包

  • 閉包是一個方法(對象)

  • 閉包定義在其餘方法內部

  • 閉包可以訪問外部方法內的局部變量,並持有其狀態(這是閉包最大的做用,能夠經過閉包的方式,將其暴露出去,提供給外部訪問)

返回Function對象(閉包)下面有一個例子:

Function makeAddFunc(int x) {
  x++;
  return (int y) => x + y;
}

main() {
  var addFunc1 = makeAddFunc(2);
  var addFunc2 = makeAddFunc(4);
  print(addFunc1(3));  // 6
  print(addFunc2(3));  // 8
}

...

// 你們能夠先想想結果爲何是 6 和 8 ?

複製代碼

畫圖一貫醜,不要介意。不明白直接留言,知無不言

函數別名

普通的函數定義。在賦值以後,會丟失函數簽名信息。

使用typedef 給函數起一個別名,使用比較方便。例如定義一個方法的回調,直接使用別名定義

void main() {
  // 函數別名
  MyAlias myAlias;
  // 能夠指向任何同簽名的函數
  myAlias = subtsract;
  myAlias(4, 2);		// subtsract: 2
  myAlias = divide;
  myAlias(4, 2);		// divide: 2
    
  // typedef 做爲參數傳遞給函數 
  calculator(4, 2, subtsract); // subtsract: 2
}

// 函數別名
typedef MyAlias(int a, int b);
// 根據MyAlias相同的函數簽名定義兩個函數
subtsract(int a, int b) {
  print('subtsract: ${a - b}');
}

divide(int a, int b) {
  print('divide: ${a / b}');
}

// typedef 也能夠做爲參數傳遞給函數
calculator(int a, int b, MyAlias func) {
  func(a, b);
}
複製代碼

再來個好玩的,我就不講了哈,Demo3 你們本身玩一玩,能夠貼到留言裏哈

void main() {          // 主入口
 Fun1 fun1;
  
 fun1 = add;
  
 Demo1(fun1, 1, 2);     // sum1 = 3
 Demo2(fun1, 1, 2);     // sum2 = 3
 // Demo3() ... ???
}

typedef Fun1(int a, int b);
typedef Fun2<T, K>(T a, K b);

int add(int a, int b) {
  print('a + b');
  return a + b;
}

Demo1(int f(int a, int b), int x, int y) {
  var sum = f(x, y);
  print("sum1 = $sum");
}

Demo2(Fun1 f, int x, int y) {
  var sum = f(x, y);
  print("sum2 = $sum");
}

Demo3(Fun2<int, int> f, int x, int y) {
  var sum = f(x, y);
  print("sum3 = $sum");
}
複製代碼

函數遞歸

遞歸這個沒啥好講的,跟其餘語言都差很少,留一個例子,經過方法的遞歸求和

main() {
  var sum = 0;
  fn(int n) {
    sum += n;
    if (n == 0) {
      return;
    }
    fn(n - 1);
  }

  fn(100);
  print(sum);
}
複製代碼

結尾

Dart 要想飛的高基礎要打牢篇一(變量與操做符) 我的博客 能夠根據博客右上角的 qq 圖標直接聯繫我哈

在寫這篇文章的時候我都不知道該怎麼樣去講函數,雖然短短一篇文章但我也是絞盡腦汁,寫的很差請你們見諒,你們湊合看哈

相關文章
相關標籤/搜索