文章目錄
- 前言
- 1. 類型聲明
- 2. 數據類型
- 2.1 基本數據類型
- 常量
- 2.2 String
- 2.3 集合
- 2.4 unicode
- 3. Dart函數特征
- 3.1 可變參數列表和默認入參
- 3.2 匿名函數
- 3.3 typedef
- 4. Dart面向對象
- 4.1 構造函數
- 4.2 訪問權限
- 4.3 類的繼承
- 參考資料
- 附錄
前言
每個語言都有控制流語句就不寫測試代碼了。
Win11代碼測試方式:
你要把電腦中的flutter和dart環境都安裝上,然后在Android Studio中新建一個Dart項目或Flutter項目即可測試
沒有安裝的可以參考本文:https://blog.csdn.net/qq_41872247/article/details/139375636
新建一個dart文件,void main就可以在編譯器運行。
1. 類型聲明
dart支持以下幾種類型聲明方式:
- 和Java一模一樣的強類型聲明。
- var開頭直接聲明一個對象,他會自己做類型推斷(同kotlin或者js)。
- dynamic聲明,可變類型對象,就是可以動態賦值為不同的類型,編譯時對于dynamic聲明的對象不做類型檢查。
- Object聲明,同dynamic,但是編譯時會將類型確定為Object,除了Object自帶的方法以外無法通過編譯(其實就是Java的Object)。
void main() {Obj obj = new Obj();obj.func();var obj1 = new Obj();obj1.func();var obj2;obj2 = new Obj1();obj2.funcc();dynamic obj3 = Obj();obj3.func();obj3 = Obj1();//obj3.func(); 可以編譯,但是無法運行obj3.funcc();Object obj4 = 3;//obj4 = obj4 + 4; 通不過編譯obj4 = "asdqwd";//obj4 = obj4.subString(0, 3) 通不過編譯obj4 = [3, 6, 9];print(obj4);
}class Obj {void func() {print("test");}
}class Obj1 {void funcc() {print("test1");}
}
2. 數據類型
2.1 基本數據類型
在java里面,int,double這種基本數據類型是沒有自帶方法的,只有封裝的Int和Double對象才有對應的方法,dart省略了這一步,直接就可以int,double,boolean進行一些方法處理。
Dart取消了使用率不高的byte,short,long這三個基本數據類型。
void main() {//int和double都繼承num.dart這個類,里面就有相關的api。int a = -4;print(a);print(a.toDouble());print(a.abs());//long a = 1; 無法過編譯//short a = 1; 無法過編譯//byte a = 1; 無法過編譯
}
不過,雖然自動封裝了對應的API,但是仍然是基礎數據類型,是值傳遞。
void main() {int a = -4;Obj o = new Obj();test(a);test(o.a);print(a); // -4print(o.a); // -4test2(o);print(o.a); // -1
}void test(int num) {num = num + 3;
}void test2(Obj obj) {obj.a = obj.a + 3;
}class Obj {int a = -4;
}
常量
Dart同時使用const關鍵字和final關鍵字,且如果是基礎數據類型的話就不需要聲明類型,他會自行做類型推斷。
const關鍵字聲明的是常量
final聲明的是可以定義一次的變量
const a = 1; // 聲明時不需要寫var,也不需要寫int
//const Obj o = Obj(); 編譯報錯
final a1 = 1;
final Obj o1 = Obj();
late final a2; // 后續再賦值void main() {//print(a2); 運行報錯//a1 = 3; 編譯報錯a2 = 3;
}class Obj {int a = 4;
}
2.2 String
- String可以使用單引號,也可以使用雙引號,當使用雙引號的String時,內部的單引號就不需要轉義可以直接使用,反之也一樣。
- String支持用取地址符(&)拼裝變量,和kotlin的一樣
- 多個常量String拼接的時候不需要+,直接拼就行
- String前面加上字符r,會自動忽略字符串的所有轉義符。
void main() {String str0 = "外側是雙引號,內側'單引號'不用轉義符";String str1 = '外側是單引號,內側"雙引號"不用轉義符';String str2 = "外側是雙引號,內側\"雙引號\"需要用轉義符";String str3 = "外側是單引號,內側\'單引號\'需要用轉義符";String str4 = str0 + str1 + " $str0";String str5 = 'awdqwd''qwdqwd''qwdqwdqwd''qwdqwdqwd';String str6 = "adqwd""qwdqwdqwd";String str7 = "qww\nqwe";String str8 = r"qww\nwww";
}
2.3 集合
- List和數組融合,可以直接用[]創建,不需要new List(語法優化)。
- List內部沒有類型檢測,可以任意放東西進去。
- Map采用字典的方式,可以直接用{}創建,可以用[]直接修改map。(語法優化)
- 集合創建的時候可以用上const關鍵字,此時里面的數據類型只能是const類型,也就是常量。
void main() {List list = [];list.add("qqq");list.add(1);list.add(new Obj());Map map = {'qq': 'xiaobing', 'qqq':3, 'qqq1': new Obj()};map['12'] = 3;print(map);var a = new Obj();Map map1 = const {'qq': 'xiaobing', 'qqq':3, 'qqq1': a}; // a編譯不通過
}class Obj{}
2.4 unicode
- 可以輸入String中不支持的一些字符
void main() {Runes runes = new Runes('\u{1f661} \u6211');print(String.fromCharCodes(runes));
}
3. Dart函數特征
Dart的函數語法模式和Java類似,也是一樣的返回類型在前,參數列表中也是類型在前的寫法。
void main() {print(test("a", "b")); // ab
}String test(String a, String b) {return a + b;
}
同時Dart語法中的參數是kotlin同款的空類型判斷的,在參數類型后面加上?表示該參數可以傳空值,不加就不能傳了。
void main() {print(test1("a", null));
}
// ?表示b這個參數可以傳空
String? test1(String a, String? b) {if(b != null) {return a+b;}return null; // 返回類型加上?后可以返回空
}
3.1 可變參數列表和默認入參
Dart不支持Java模式的函數重載,即函數名相同,參數列表或返回類型不同的多個函數同時存在,但是對應的是,Dart的函數支持可變參數列表,可以直接自定義必須要傳入的參數和可以傳也可以不傳的參數,用花括號{}。
void main() {print(test2("a", b: "b", c: null));
}// 在花括號里面的參數就是可以傳也可以不傳的,但是加了required關鍵字的還是必須要傳的
String test2(String a, {required String b, required String? c, String d="dddd", String? e}) {var str = "";if(c != null) {str += c;}if(e != null) {str += e;}return a + b + d + str;
}// 同時,作為可變參數,required,?,默認值三個模式中至少要有一個,都沒有的話就過不了編譯
String test20(String a, {String b}) { //編譯過不去return a;
}
中括號模式:也能用做可變參數列表,但是不支持required關鍵字
void main() {print(test3("a"));
}String test3(String a, [String b="bb", String? c="ccc", String? d]) {return a;
}
// 同上,都沒有過不了編譯
String test30(String a, [String b]) { return a;
}
3.2 匿名函數
和其他語法的萬物皆可對象是一個道理,可以單獨將一個函數聲明成對象,只是具體寫法上有不同,用箭頭表明。
void main() {// 單行直接用箭頭,返回類型自動推測var a = (int a, int b) => a + b;print(a(1, 2));// 多行用花括號,返回類型自動推測var b = (int a, int b) {a = a + 1;return a + b;};print(b(1, 2));//無返回類型Function c = () => print("ccc");//print(c()); // 編譯過不去,因為c返回類型是voidc();
}
當然你懂得,函數本身當然也可以作為函數的入參
void main() {test(() => print("a"), () => print("bb"));
}void test(Function a, Function b) {a();b();
}
3.3 typedef
typedef可以讓你將一個特定入參列表的匿名函數作為一個對象的類型,然后再實際的來定義他的具體功能。
typedef實際名稱叫函數簽名,不好理解的話你可以將其理解成只有一個方法的接口。
void main() {fun1 f1 = (int a) {print("我是f1,a=" + a.toString());};// 編譯過不去,因為fun1是一個只有一個入參的方法
/* fun1 f2 = (int a, int b) {print("我是f2");};*/
}
typedef fun1(int a);typedef fun2(int a, int b);
有了這個typedef后,你在定義函數入參的時候就能更精確入參的類型了。
void main() {fun1 f1 = (int a) {print("我是f1,a=" + a.toString());};test(f1);
}typedef fun1(int a);void test(fun1 f1) {f1(555);
}
4. Dart面向對象
Dart的類的定義模式和Java基本一樣。
4.1 構造函數
首先,Dart為了方便使用Java的程序員使用Dart語法,所以他支持Java的同款構造函數,只是不支持重載構造函數。
void main() {// 三種構造函數都能用var userInfo1 = UserInfo1.con2();userInfo1 = UserInfo1("aa");userInfo1 = UserInfo1.con1("aaa", "11", "id");
}// 支持java的構造方法形式
class UserInfo {late String name;String? age;String id = "";UserInfo(String name, String age) {this.age = age;this.name = name;}
}
對于Dart語言本身,他的構造方法有個更簡單的寫法
與此同時,為了彌補不能重載構造函數的問題,Dart語言引入了建造者模式的設計模式,允許通過重命名的方式來設置多個構造函數。
//Dart自己的構造方法形式
class UserInfo1 {late String name;String? age;String id;// 構造函數直接填入成員變量,不需要再寫賦值,是語法糖UserInfo1(this.name, {this.age, this.id = ""}); UserInfo1.con1(this.name, this.age, this.id); //命名為con1的另一個構造方法UserInfo1.con2() : name = "1", age = "2", id = "3"; // 重命名,但是擁有默認實現
}
4.2 訪問權限
Dart中沒有public potect和private關鍵字,而是通過在成員變量前面增加_來標記他為私有成員變量,
注意,Dart的私有成員變量指的是本文件以外的對象無法訪問,和Java中的本對象以外的對象無法訪問不完全相同。
與此同時,對于私有成員變量他的set和get方法寫法也略微有區別。
class PrivateUserInfo {String? name;String? _age; //私有化,但是dart的私有化是該文件內可以訪問,其他文件不能訪問PrivateUserInfo(this.name, this._age);get getAge {return _age;}set setAge(String age) {this._age = age;}
}
PrivateUserInfo在ClassDemo1.dart,ClassDemo2就無法訪問了。
私有類也是同理,在類名前面加上下劃線,這里不寫案例。
4.3 類的繼承
和Java同款,唯一區別是,dart語言中沒有interface關鍵字,對于類來說,無論是extends還是implementation,他所繼承的都是類。
class c1 {String? str1;void fun1() {}
}abstract class c2 {String? str2;void fun2();
}class c3 extends c2 implements c1 {String? str1; // 因為implementation,必須加上c1的成員變量void fun1() { // 因為implementation,必須加上c1的方法}void fun2() { // 因為c2的fun2是抽象方法,必須進行實現}
}
參考資料
https://blog.csdn.net/haodawang/article/details/83031378