學Flutter就和學iOS一樣搔确,先學基本語言語法的使用竟秫,再學習搭UI娃惯,iOS是OC和Swift,F(xiàn)lutter么就是Dart肥败,語言學多了語法都差球不多趾浅,特別是這些新的語言,很多東西都是相似的馒稍,但是長時間不用容易忘記皿哨,與其每次去網上瞎jb找,不如自己總結一些纽谒,以后看自己寫的東西就行了证膨。文中個別結論是我自己總結出來的,不能保證準確性鼓黔,看到的同學僅供參考央勒。
本章提綱:
1.函數(shù)
2.函數(shù)的參數(shù)
3.匿名函數(shù)
4.運算符
函數(shù)
1.Dart也是面向對象語言,所以即使函數(shù)也是對象澳化,所有也有類型崔步,函數(shù)的類型就Function
,這個和Swift中一樣的哇缎谷,函數(shù)都是一等公民井濒,意味著你可以將函數(shù)作為變量定義或者作為其他函數(shù)的參數(shù)或者返回值。如果函數(shù)中只有一個表達式列林,那么可以使用箭頭語法(arrow syntax)瑞你。
//定義一個函數(shù)
int sum(num num1, num num2) {
return num1 + num2;
}
//省略返回值的類型依然是可以的
sum(num num1, num num2) {
return num1 + num2;
}
//注意,這里面只能是一個表達式希痴,不能是一個語句
sum(num1, num2) => num1 + num2;
函數(shù)的參數(shù)
1.函數(shù)的參數(shù)可以分成兩類: 必須參數(shù)和可選參數(shù)者甲,必須參數(shù)么就是函數(shù)基本的參數(shù)江醇,可選參數(shù)可以分為命名可選參數(shù)和位置可選參數(shù)岗照。
// 命名可選參數(shù)父丰,age和height就是可選參數(shù)
printInfo1(String name, {int age, double height}) {
print('name=$name age=$age height=$height');
}
// 調用printInfo1函數(shù)
printInfo1('tong'); // name= tong age=null height=null
printInfo1('tong', age: 18); // name= tong age=18 height=null
printInfo1('tong', age: 18, height: 1.88); // name= tong age=18 height=1.88
printInfo1('tong', height: 1.88); // name= tong age=null height=1.88
2.命名可選參數(shù)粪薛, 可以指定某個參數(shù)是必傳的,使用@required
標記寇钉,這點在第一次看的時候不是很理解刀疙,因為既然是可選參數(shù)了,為啥又可以要求必傳扫倡,要求必傳直接設為必傳參數(shù)不就行了谦秧,這兩者感覺有點矛盾,后來看官方很多類里面都這么用的撵溃,目前還沒體會到這種用法的優(yōu)勢在哪疚鲤。
補充:看到后面官方文檔有個解釋我覺得還算能說的過去,就是為啥不用必傳參數(shù)是因為在Flutter里很多widget的屬性很多缘挑,如果用必傳參數(shù)調用的時候看不到方法名集歇,不知道傳的是哪個參數(shù),而使用命名可選+@requierd
就可以實現(xiàn)既可以看到方法名语淘,方便外部調用诲宇,也可以有必傳參數(shù)的限制了,更多的是方便使用惶翻。
intInfo3(String name, {int age, double height, @required String address}) {
print('name=$name age=$age height=$height address=$address');
}
3.位置可選參數(shù)姑蓝,調用的時候參數(shù)的順序不能調換。
// 定義位置可選參數(shù)
printInfo2(String name, [int age, double height]) {
print('name=$name age=$age height=$height');
}
// 調用printInfo2函數(shù)
printInfo2('why'); // name=why age=null height=null
printInfo2('why', 18); // name=why age=18 height=null
printInfo2('why', 18, 1.88); // name=why age=18 height=1.88
4.可選參數(shù)默認值
// 參數(shù)的默認值
printInfo4(String name, {int age = 18, double height=1.88}) {
print('name=$name age=$age height=$height');
}
函數(shù)是一等公民
上面說過了吕粗,可以把函數(shù)當做其他類型的變量一樣在各個場合使用纺荧。
main(List<String> args) {
// 1.將函數(shù)賦值給一個變量
var bar = foo;
print(bar);
// 2.將函數(shù)作為另一個函數(shù)的參數(shù)
test(foo);
// 3.將函數(shù)作為另一個函數(shù)的返回值
var func =getFunc();
func('tong');
}
// 1.定義一個函數(shù)
foo(String name) {
print('傳入的name:$name');
}
// 2.將函數(shù)作為另外一個函數(shù)的參數(shù)
test(Function func) {
func('tong');
}
// 3.將函數(shù)作為另一個函數(shù)的返回值
Function getFunc() {
return foo;
}
匿名函數(shù)
沒有名字的函數(shù)又稱為匿名函數(shù),也可以叫l(wèi)ambda或者closure颅筋,這玩意兒基本每種語言里都有宙暇,叫法不一樣,OC叫block议泵,原理都差不多占贫。
main(List<String> args) {
// 1.定義數(shù)組
var movies = ['西游記', '東游記', '南游記', '北游記'];
// 2.使用forEach遍歷: 有名字的函數(shù)
printElement(item) {
print(item);
}
movies.forEach(printElement);
// 3.使用forEach遍歷: 匿名函數(shù)
movies.forEach((item) {
print(item);
});
movies.forEach((item) => print(item));
}
函數(shù)返回值
所有函數(shù)都返回一個值。如果沒有指定返回值肢簿,則隱式返回null附加到函數(shù)體。
運算符
基本的+-*/和其他語言一樣蜻拨,主要記錄一下Dart特有的幾個運算符池充。
1.整除運算~/
var num = 7;
print(num ~/ 3); // 整除操作, 結果2;
2.??=
賦值操作
當變量為null
時,使用后面的內容進行賦值缎讼。當變量有值時收夸,使用自己原來的值。
main(List<String> args) {
// var name2 = 'tong';
var name2 = null;
name2 ??= 'chao';
print(name2); // 當name2初始化為tong時血崭,結果為tong卧惜,當初始化為null時厘灼,賦值了chao
}
3.條件運算符??
expr1 ?? expr2
,如果expr1
是null
咽瓷,則返回expr2
的結果设凹;如果expr1
不是null
,直接使用expr1
的結果茅姜。
var temp = 'why';
var temp = null;
var name = temp ?? 'kobe';
print(name);
4.級聯(lián)語法:..
可以對一個對象進行連續(xù)的操作闪朱。除了調用函數(shù),還可以訪問同一對象上的字段屬性钻洒。 這通撤茏耍可以節(jié)省創(chuàng)建臨時變量的步驟,同時編寫出更流暢的代碼素标。
main(List<String> args) {
final p1 = Person();
p1.name = 'tong';
p1.run();
p1.eat();
p1.swim();
//級聯(lián)語法
final p2 = Person()
..name = "tong"
..run()
..eat()
..swim();
}
5.類型判定運算符
as
称诗,is
,和 is!
運算符用于在運行時處理類型檢查头遭。is
運算符判斷對象是否為某種類型寓免,as
運算符將對象強制轉換為特定類型。
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
(emp as Person).firstName = 'Bob';
如果emp
為null
或者不是Person
對象任岸, 那么第一個is
的示例再榄,后面將不回執(zhí)行; 第二個as
的示例會拋出異常享潜。
6.?.
取值操作
使?.
來代替.
困鸥,可以避免因為左邊對象可能為null
,導致的異常:
// 如果 p 為 non-null剑按,設置它變量 y 的值為 4疾就。
p?.y = 4;
運算符重寫
有的語言里叫運算符重載,都是為原來不支持這種操作的數(shù)據類型賦予這種運算的能力艺蝴,方便使用猬腰。這玩意兒OC也沒有,古老特點之三猜敢。
重載時需要用到operator
這個關鍵字姑荷,后面跟上要重載的運算符,下面就舉個簡單的+
和-
重載的例子缩擂,其他的用法還蠻多鼠冕,==
的重載還要涉及到hash
和isEqual
吧,這個應該所有語言都差不多胯盯,具體的可以去網上專門搜一下懈费,貼個
傳送門,這具體用到的時候再細看吧博脑。
class Vector {
final int x, y;
Vector(this.x, this.y);
Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
}
流程控制
1.for循環(huán)
除了基本的for-i和for-in循環(huán)之外憎乙,Dart對于實現(xiàn)了Iterable 接口的對象提供了forEach() 方法票罐,如果不需要使用當前計數(shù)值, 使用 forEach()
是非常棒的選擇泞边。
candidates.forEach((candidate) => candidate.interview());
2.switch-case
每個case
結尾需要加break
该押,空case
可以穿透,在非空case
中實現(xiàn)fall-through形式繁堡,可以使用continue
語句結合lable的方式實現(xiàn):
var command = 'CLOSED';
switch (command) {
case 'CLOSED':
executeClosed();
continue nowClosed;
// Continues executing at the nowClosed label.
nowClosed:
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}