Flutter系列1-Dart基礎筆記
1、變數宣告及命名規則
1、簡介
Dart的開始處,是因為我看見了flutter。其實對於一個會 javaScript 和 java 的來說這些都是理所當然的。我學習的時候比較喜歡記筆記所以我記錄一些這些東西。
其實如果會一些語言,Dart根本不需要花時間。
2、宣告
dart 是一個強大的指令碼類語言,可以不預設先定義變數型別,自動會型別推倒
dart 中定義變數可以通過var關鍵字可以通過型別來申明變數
如:
var str = 'this is var';
String str = 'this is var';
int str = 123
void main() { var str = '你好dart'; var numx = 1234; print(str); print(numx); String str1 = '你好dart'; print(str); int numx1 = 123; print(numx1); }
定義報錯:
var str = '';
str = 1234; //報錯 A value of type 'int' can't be assigned to a variable of type 'String'.
print(str);
String str = 12312;//報錯 A value of type 'int' can't be assigned to a variable of type 'String'.
3、命名規則
一、Dart命名規則:
1、變數名稱必須有數字、字母、下劃線和美元符號($)組成
2、注意:識別符號開頭不能是數字
3、識別符號不能是保留字和關鍵字
4、變數的名字是區分大小寫的如:age和Age是不同的變數。在實際的運用中也建議不要用一個
5、識別符號(變數名稱)一定要見名思意:變數名稱建議用名詞,方法名稱建議用動詞
二、Dart常量:final和const修飾符
const 值不變 一開始就得賦值
final 可以開始不賦值但是隻能賦值一次;而final不僅僅有const的編譯時常量的特性,最重要的它是執行時常量,並且final是惰性初始化,即在執行時第一次使用前才初始化。可以見下面定義時間的例子。
永遠不變的量,例如 PI = 3.1415926,請使用final或const修飾它,而不是使用var或其他變數型別
final name = "Bob"; final String strname = "Bobby"; const bar = 1000000; const double a = 1.123 * bar; final date1 = new DateTime.now(); const date2 = new DateTime().now();//報錯,New expression is not a constant expression.
2、Dart的資料型別
Dart中支援以下資料型別:
一、常用資料型別:
numbers(數值):int、double
String(字串):String
Booleans(布林):bool
List(陣列):在Dart中,陣列是列表物件,所以大多數人只是稱它們為列表
Maps(字典):通常來說,Map是一個鍵值對相關的物件。鍵和值可以是任何型別的物件。每個 鍵
1、number型別
int 必須時整型
double 既可以是整型也可以是浮點型
2、String型別
String 定義時 “”“ 單引號定義會保持格式
String str1 = '111';
String str2 = "222";
String str3 = ''' 111
111''';
print(str1);
print(str2);
print(str3);
執行結果:
String字串的拼接
String str1 = '你好';
String str2 = "Dart";
print("$str1 $str2");
print(str1 + str2);
3、Boolean型別
bool flag = true;
print(flag);
4、List(陣列/集合)
var l1 = ['aaa','bbb','ccc'];
print(l1);
print(l1.length);
print(l1[0]);
//輸出:
//[aaa, bbb, ccc]
//3
//aaa
var l2 = new List();
l2.add("111");
l2.add("222");
l2.add("333");
print(l2);
//輸出:[111, 222, 333]
//定義list指定型別
var l3 = List<String>();
l3.add("111");
l3.add(222);//報錯,Error: The argument type 'int' can't be assigned to the parameter type 'String'.
print(l3);
5、Maps(字典)
//key必須加上 " 號
var person = {
"name" : "張三",
"age" : 20,
"like" : ["111","222"]
};
print(person);
//輸出:{name: 張三, age: 20, like: [111, 222]}
print(person["name"]);
//輸出:張三
var p = new Map();
p["name"] = "張三";
p["age"] = 20;
p["like"] = ["111","222"];
print(p);
//輸出:{name: 張三, age: 20, like: [111, 222]}
二、很少用的資料型別:
Runes:Rune是UTF-32編碼的字串。它可以通過文字轉換成符號表情或者代表特定的文字。
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes('\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
Symbols:Symbol物件表示在Dart程式中宣告的運算子或識別符號。
三、判斷資料型別
is 關鍵字判斷資料型別
var str = '1234';
if(str is String){
print('是String型別');
}else {
print('其他');
}
//輸出:是String型別
3、Dart算術運算子/條件表示式/型別轉化
1、運算子
1、算術運算子
+ - * / ~/(取整) %
2、關係運算符
== != > < >= <=
3、邏輯運算子
! && ||
4、賦值運算子
基礎賦值運算子 = ??=
複合賦值運算子 += -= *= /= %= ~/=
int b =10;
b??= 23;
print(b);//輸出:10
int b ;
b??= 23;
print(b);//輸出:23
//上述 ??= 表示如果b為空的話,才進行賦值操作
2、條件表示式
1、if else switch case
2、三目運算子
bool flag = true;
String c = flag? 'true':'false';
print(c);//輸出true
3、?? 運算子
var a ;
var b = a ?? 10;
print(b);//輸出10
var a = 7 ;
var b = a ?? 10;
print(b);//輸出7
3、型別轉化
1、number與String型別之間的轉換
number型別轉換成String型別 toString()
String型別轉換成number型別 parse
String str = '123';
var numx = int.parse(str);
print(numx is int);//輸出true
2、其他型別轉換成Booleans型別
4、Dart迴圈語句
1、for基本語法
for(int i = 1 ; i <= 100 ;i++){
print(i);
}
2、while/do…while
int i = 1;
while(i <= 10){
print(i);
i++;
}
do{
print("總會執行一次");
}while(i < 2);
3、continue/break
continue:結束本次迴圈,但是還是會繼續執行當前迴圈。
break:跳出當前迴圈體,結束當前迴圈,但是隻能向外跳出一層。
5、Dart集合型別List/Set/Map
1、List
1、常用屬性
length(長度)、reversed(翻轉)、isEmpty(是否為空)、isNotEmpty(是否不為空)
2、常用方法
add(增加)、addAll(拼接陣列)、indexOf(查詢,需傳入具體值)、remove(刪除,需傳入具體值)、removeAt(刪除,傳入索引值)、fillRange(修改)、insert(index,value)指定位置插入、insertAll(index,list)指定位置插入List、toList(其他型別轉化成List)、join(List轉換成字串)、split(字串轉換成List)
2、Set
set是沒有順序且不能重複的集合。
3、Map
1、常用屬性
keys:獲取所有的key值,values:獲取所有的values值,isEmpty:是否為空,isNotEmpty:是否不為空
2、常用方法
remove(key):刪除指定key的資料、addAll({…}):合併對映,給對映內增加屬性、containsValues:檢視對映內的值,返回true/false
4、迴圈語句 forEach map where any every
List myList = ["111", "222", "333"];
myList.forEach((value) {
print(value);
});
//輸出:
//111
//222
//333
List myListnumx = [1, 2, 3, 4];
var newList = myListnumx.map((e) {
return e * 2;
});
print(newList);//(2, 4, 6, 8)
var newListWhere = myListnumx.where((e) {
return e > 2;
});
print(newListWhere);//(3, 4)
//只要有一個滿足條件即返回true
var f = newList.any((element) {
return element > 2;
});
print(f);//true
//全部滿足返回true
var d = newList.every((element) {
return element > 2;
});
print(d);//false
6、Dart中的函式
1、函式的定義
void main(List<String> args) {
var n = getnumx();
print(n);//123
printInfo();//自定義方法!
}
void printInfo() {
print("自定義方法!");
}
int getnumx() {
return 123;
}
void main(List<String> args) {
print(sum(1,2));//3
print(sumd(1,2));//3
}
int sum(int a,int b){
return a+b;
}
int sumd(a,b){
return a+b;
}
2、可選引數
void main(List<String> args) {
print(getStr("xxx"));//xxx
print(getStr("xxx",12));//xxx 12
}
String getStr(String name,[int age]){
if(age != null){
return "$name $age";
}else {
return name;
}
}
3、預設引數
void main(List<String> args) {
print(getStr("xxx"));//xxx 男
print(getStr("xxx","女",20));//xxx 20 女
}
String getStr(String name,[String sex = '男',int age]){
if(age != null){
return "$name $age $sex";
}else {
return "$name $sex";
}
}
4、命名引數
注意:傳參和函式那邊的{ }裡面的key定義一致。
void main(List<String> args) {
print(getStr("xxx"));//xxx 男
print(getStr("xxx",sex:"女",age:20));//xxx 20 女
}
String getStr(String name,{String sex = '男',int age}){
if(age != null){
return "$name $age $sex";
}else {
return "$name $sex";
}
}
5、箭頭函式
main(List<String> args) {
List list = ["111","222","333"];
list.forEach((element) => {
print(element) //這裡面不打分號,只能寫一行,注意啊
});
}
6、匿名函式
main(List<String> args) {
//fun是匿名函式
var fun = (){
print("xxxx");
};
fun();
}
7、自執行方法
main(List<String> args) {
((){
print("自執行方法!");
})();
}
8、方法的遞迴
main(List<String> args) {
var sum =1;
fn(n) {
sum+=n;
if(n==0){
return;
}
fn(n-1);
}
fn(100);
print(sum);
}
9、閉包
全域性變數:全域性變數常駐記憶體、全域性變數汙染全域性
區域性變數:不常駐記憶體會被垃圾回收機制回收、不會汙染全域性
閉包實現:常駐記憶體但是不汙染全域性
閉包通俗點講就是函式巢狀函式,並且返回裡面的函式。
main(List<String> args) {
fn(){
var a = 1;
return (){
a++;
print(a);
};
}
var b = fn();
b();//2
b();//3
b();//4
}
7、Dart中的物件
1、面向物件簡介
面向物件程式設計(OOP)的三個基本特徵是:封裝、繼承、多型
封裝:封裝是物件和類概念的主要特徵。封裝,把客觀事物封裝成抽象的類,並且把自己的部分屬性和方法提供給其他物件。
繼承:面向物件程式語言的一個主要的功能就是”繼承“。繼承可以說是一種能力,繼承實際上也是為了提高程式碼的複用性和可擴充套件性。繼承是使用已存在的類的定義作為基礎建立新類的技術,新類的定義可以增加新的資料或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。
多型:允許將子型別的指標賦值給父類型別的指標,同一個函式呼叫會有不同的執行效果。
Dart也不例外,所有東西都是物件,所有的物件都繼承自Object類。
Dart可以說是一門使用類和單繼承的面嚮物件語言,所有的物件都是類的例項,並且所有的類都是Object的子類。一個類通常由屬性和方法組成。
2、類的建立
class Person{
String name = "cdx";
int age = 23;
void getInfo(){
print("${this.name} ${this.age}");
print(this.name + " "+ this.age.toString());
}
void setInfo(age){
this.age = age;
}
}
main(List<String> args) {
var p1 = new Person();
print(p1.age); //23
p1.getInfo();//cdx 23 cdx 23
p1.setInfo(18);
print(p1.age);//18
}
3、建構函式
class Person{
String name = "cdx";
int age = 23;
//預設建構函式
Person(){
print("建構函式");
}
void getInfo(){
print("${this.name} ${this.age}");
}
}
main(List<String> args) {
var p1 = new Person();
}
//輸出:建構函式
class Person{
String name = "cdx";
int age = 23;
Person(String name , int age){
this.name = name;
this.age = age;
}
//簡寫形式
// Person(this.name,this.age);
void getInfo(){
print("${this.name} ${this.age}");
}
}
main(List<String> args) {
var p1 = new Person("zs",12);
p1.getInfo();//zs 12
var p2 = new Person("ls",16);
p2.getInfo();//ls 16
}
注意:預設的建構函式只能定義一個。
4、命名建構函式
預設建構函式只能定義一個但是命名建構函式可以定義多個。
class Person{
String name = "cdx";
int age = 23;
//預設建構函式
Person(this.name,this.age);
Person.now(){
print("命名建構函式");
}
void getInfo(){
print("${this.name} ${this.age}");
}
}
main(List<String> args) {
var p1 = new Person.now();//命名建構函式
}
5、私有屬性/私有方法
Dart中是沒有和java一樣有public、private、protected這些訪問修飾符的。
方法:將類抽離成一個檔案,使用 “ _ ” 把一個方法或者屬性變成私有的。
6、getter與setter修飾符
class Rect {
num height;
num width;
Rect(this.height,this.width);
get area{
return this.height * this.width;
}
set areaHeight(value){
this.height = value;
}
}
main(List<String> args) {
Rect r = new Rect(10, 2);
print("面積為:${r.area}");//注意呼叫直接通過訪問屬性的方式訪問area
r.areaHeight = 6;
print("面積為:${r.area}");
}
7、靜態成員
1、使用static關鍵字來實現類級別的變數和函式。
2、靜態方法不能訪問非靜態成員,非靜態方法可以訪問靜態成員。
class Person {
static String name = 'cdx';
static void showName() {
print(name);
}
}
main(List<String> args) {
print(Person.name);
Person.showName();
}
class Person {
static String name = 'cdx';
int age = 23;
static void showName() {
print(name);
}
void printInfo(){ //非靜態方法可以訪問靜態成員以及非靜態成員
print(name);//訪問靜態屬性
print(this.age);//訪問非靜態屬性
}
}
main(List<String> args) {
Person p = new Person();
p.printInfo();
}
8、操作符
?:條件操作符 as:型別轉換 is:型別判斷 …:級聯操作
class Person {
String name = 'cdx';
int age = 23;
void printInfo(){
print("${this.name} ${this.age}");
}
}
main(List<String> args) {
Person p1 = new Person();
p1.printInfo();//cdx 23
Person p2;
//p2.printInfo();//報錯:The method 'printInfo' was called on null.
p2?.printInfo();
}
p as Person //型別轉換
class Person {
String name = 'cdx';
int age = 23;
void printInfo(){
print("${this.name} ${this.age}");
}
}
main(List<String> args) {
Person p1 = new Person();
p1.printInfo();//cdx 23
p1..name='xxx'
..age =20
..printInfo();//xxx 20
}
9、繼承
1、子類使用extends關鍵詞來繼承父類
2、子類會繼承父類裡面可見的屬性和方法但是不會繼承建構函式
3、子類能複寫符類的方法 getter和setter
class Person {
String name = 'cdx';
int age = 23;
Person(this.name,this.age);
void printInfo(){
print("${this.name} ${this.age}");
}
}
class Cdx extends Person{
String sex;
Cdx(String name, int age,String sex) : super(name, age){
this.sex = sex;
}
void printCdx(){
print("${this.name} ${this.age} ${this.sex} ");
}
}
main(List<String> args) {
Cdx c = new Cdx('xxx',20,'男');
c.printInfo();//xxx 20
c.printCdx();//xxx 20 男
}
10、抽象類
Dart中抽象類主要用於定義標準,子類可以繼承抽象類,也可也實現抽象類介面。
1、抽象類通過abstract關鍵詞來定義。
2、Dart中的抽象方法不能用abstract宣告,Dart中沒有方法體的方法稱為抽象方法。
3、如果子類繼承抽象類必須要實現裡面的抽象方法。
4、如果把抽象類當作介面實現的話,必須要實現抽象類裡面定義的所有屬性和方法。
5、抽象類不能被例項化,但可以繼承它的子類
extends抽象類和implements的區別:
1、如果要複用抽象類裡面的方法,並且要用抽象方法約束子類的話我們就要用extends繼承抽象類。
2、如果只是把抽象類當作標準的話我們就要用implement實現抽象類。
//定義一個Animal類必須要求它的子類包含eat方法
//解決方法:用到抽象類
abstract class Animal{
eat();//抽象方法
}
class Dog extends Animal{
@override
eat() {
print("eat");
}
}
main(List<String> args) {
Dog dog = new Dog();
dog.eat();
}
11、多型
允許將子類型別的指標賦值給父類型別的指標,同一個函式呼叫會有不同的執行效果。
子類的例項賦值給父類的引用。
多型就是父類定義一個方法不去實現,讓繼承他的子類去實現,每個子類有不同的表現。
abstract class Animal{
eat();//抽象方法
}
class Dog extends Animal{
@override
eat() {
print("Dog eat");
}
}
class Cat extends Animal{
@override
eat() {
print("Cat eat");
}
}
main(List<String> args) {
Animal dog = new Dog();
dog.eat();//Dog eat
Animal cat = new Cat();
cat.eat();//Cat eat
}
12、介面
和java一樣Dart也是有介面的他們之間案對區別是
Dart的介面沒有interface關鍵字定義介面,而是普通類或抽象類都可以作為介面被發現
但是Dart還是有不一樣的地方,如果實現的類是普通類,會將普通類和抽象中的屬性的方法全部需要覆蓋寫一遍。而因為抽象類可以定義抽象方法,普通類不可以,所有一般來說如果要實現java介面那樣的方式,一般使用抽象類。當然也建議使用抽象類定義介面。
abstract class Db{
String url;
add();
save();
delete();
}
class Mysql implements Db{
@override
String url;
Mysql(this.url);
@override
add() {
print("Mysql add");
}
@override
delete() {
print("Mysql delete");
}
@override
save() {
print("Mysql save");
}
}
main(List<String> args) {
Mysql mysql = new Mysql("xxxxxxx");
}
13、mixins
中文的意思是混入,其實就是在類中混入其他功能。比如說使用它實現類似多繼承的功能。
但是隨著Dart版本的不斷變化,下面講一下Dart中2.x中使用mixins的條件
1、作為mixins的類只能繼承自Object,不能繼承其他類。
2、作為mixins的類不能有建構函式
3、一個類可以mixins多個mixins類
4、mixins絕不是繼承,也不是介面,而是一一種全新的特性。
//A,B不能繼承其他類,而且A,B不能有建構函式
class A{
void printA(){
print("A");
}
}
class B{
void printB(){
print("B");
}
}
class C with A,B {
}
main(List<String> args) {
var c = new C();
c.printA();
c.printB();
}
8、泛型
泛型就是解決,類、介面、方法的複用性,以及對不特定資料型別的支援(型別校驗)。
T getData<T>(T value){
return value;
}
main(List<String> args) {
print(getData(21));
print(getData<String>('xxxx'));
}
class PrClass<T> {
List list = new List<T>();
void add(T value) {
this.list.add(value);
}
void printInfo() {
for (var i = 0; i < this.list.length; i++) {
print(this.list[i]);
}
}
}
main(List<String> args) {
PrClass p = new PrClass<String>();
p.add("111");
//p.add(1);//type 'int' is not a subtype of type 'String' of 'value'
p.printInfo();//輸出:111
}
9、Dart中的庫
在Dart中,庫的使用是通過import關鍵字引入的。
library指令可以建立一個庫,每個Dart檔案都是一個庫,即使沒有使用library指令來指定。
Dart中的庫主要分為三種:
1、我們自定義的庫
import 'lib/xxx.dart'
2、系統內建庫
import 'dart:math';
import 'dart:io';
import 'dart:convert';
//等等
3、第三方包管理系統中的庫(一般pub中)。
有很多不一一舉例了。
1、需要在自己專案根目錄新建一個pubspec.yaml。
2、在pubspec.yaml檔案中配置名稱、描述、依賴資訊。
3、執行pub get 獲取包下載到本地。
4、專案中引入該庫。
4、最後就是看文件使用它。
10、擴充套件一下async和await
async和await
這兩個關鍵詞的使用只需要記住:
1、只有async方法才能使用await關鍵字呼叫方法。
2、如果呼叫別的async方法必須使用await關鍵字。
async是讓方法變成非同步。
await是等待非同步方法執行完成。
main(List<String> args) async{
var result = await testAsync();
print(result);
}
//非同步方法
testAsync() async{
return 'async';
}