衆所周知,Dart是一門面向對象的語言,比Java更純粹,Dart中的方法也是對象,也有類型Function。這意味着方法能夠被分配給對象,也能夠當作參數傳遞給其餘方法。javascript
這裏咱們先定義一個返回值爲void,入參爲一個int的printElement
方法,它的做用很簡單,就是打印這個int值。html
接着咱們初始化一個數組,而後將printElement
方法當作參數傳遞給咱們的list.forEach
方法,這樣咱們將list中的每一個元素,依次交給printElement
方法去打印。前端
void printElement(int element) {
print(element);
}
main() {
var list = [1, 2, 3];
// Pass printElement as a parameter.
list.forEach(printElement);
}
複製代碼
若是不太好理解的話,能夠看下list.forEach方法源碼,也就是Iterator#forEach(),以下所示。java
/**
* Applies the function [f] to each element of this collection in iteration
* order.
*/
void forEach(void f(E element)) {
for (E element in this) f(element);
}
複製代碼
能夠看出,咱們的forEach方法接受的參數是一個方法,該方法的返回值void,一個入參f,入參類型這裏用的是泛型。git
方法內部調用了for循環,依次獲取到Iterator(也就是咱們的List)中的元素element,而後將element做爲參數傳遞給f方法,同時調用這個f方法。這個f方法就是咱們以前傳入的printElement
方法。github
接下來咱們重點說下幾個細節。api
一、第一個細節,就是方法當作參數傳遞
的時候,只須要傳遞方法名
便可,不須要帶上方法的括號
。具體請看咱們的printElement
方法是如何定義,以及是如何傳遞給list.forEach
方法的。數組
二、方法做爲參數的時候傳遞給其餘方法的時候,不會當即執行。bash
方法當作參數傳遞的時候,方法名錶示該方法的引用,這個引用當作參數傳遞的時候不會當即執行,只會再調用的時候執行。ide
三、入參方法在被實際調用時,會添加括號,當作正常的方法調用。
具體請看printElement
方法當作參數傳遞給list.forEach
方法的過程,以及list.forEach
方法內部是如何調用入參方法f的。
這裏之因此一再強調方法調用有沒有括號,是由於我在這裏吃過虧,另外一方面對這些細節理解到位有助於咱們加深對Dart語言的理解。
咱們看個例子就明白了。
這裏咱們定義一個add方法,返回值爲int,入參爲兩個int。
而後定義一個test方法,返回值爲int,前兩個入參都是int類型,第三個參數是Function類型。
而後在main方法中,將add方法做爲參數傳遞給test方法,並打印test方法的執行結果。
int add(int a, int b) {
return a + b;
}
int test(int a, int b, Function operation) {
return operation(a, b);
}
main() {
print(test(5, 2, add));
}
複製代碼
這裏add方法
當作參數傳遞時值傳遞了方法名add
,沒有括號也沒有參數,一塊兒跟預期同樣。
接下來咱們修改下main方法中的測試方法,咱們第三個參數修改成add(1,1)
,代碼以下所示:
main() {
print(test(5, 2, add(1,1)));
}
複製代碼
具體錯誤提示以下:
提示的意思是說,int類型的參數不能賦值給Function類型的參數,也就是咱們的add(1,1)
結果爲int
,跟test方法中定義的第三個入參的類型不匹配。
好了,咱們應該已經看到方法名(不帶括號)和方法執行語句(帶括號)的區別了。
結論以下:
在java中,方法不是對象,因此咱們不會遇到將方法當作參數傳遞給其餘方法
這種狀況。咱們常常使用的事直接將方法執行語句(也就是它們的返回值)做爲參數直接傳遞。
最後,Flutter和Dart語言的不少思想和語法,都是參考或照搬的前端,若是學習或開發中遇到困惑,那麼從前端查起應該會容易好多。
In dart , What does passing a function or a class without "()" parenthesis does?
Lint rules: unnecessary_lambdas