主要講一些注意點,跟主流語言差不多的就不講了。目測0基礎學習Dart的人應該很少甚至沒有吧。主要是移動端開發和前端開發學習。歡迎評論歡迎來撕。
變量
先展示下幾種變量的聲明方式,然后再說下區別
void main() {
//var 聲明時 不初始化
var a;
a = false;
a = 123;
a = 'test';
print(a);
//var 聲明時 初始化
var b = false;
// b=123; 編譯器報錯
// b='test';
print(b);
//dynamic
dynamic c = false;
c = 123;
c = 'test';
print(c);
//Object
Object d = false;
d = 123;
d = 'test';
//明確具體類型
String e = 'test';
print(e);
}
var
首先要明確的是:Var只是個關鍵字,編譯器會根據賦值反推其聲明的類型。
聲明時不進行初始化
//聲明時 不初始化
var a;
a = false;
a = 123;
a = 'test';
print(a);
這個情況,后面變量可以隨意更改指向的對象類型。
聲明時 進行初始
聲明直接初始化,則變量的能指向的引用類型被固定,之后這個變量就不能指向其他類型對象。
dynamic
先看下與var的區別,它即使是在聲明時進行了初始化,后面還能指向其他類型的對象。如下
dynamic c = false;
c = 123;
c = 'test';
print(c);
這是為什么呢?
首先dynamic不是關鍵字,它表示一種未知類型,所以它可以表示所有類型
其次 dynamic聲明的變量類型是在運行時才確定,所以編譯器在編譯時不會檢查
個人感覺類似于java中泛型里常用的T,同時它在Dart的常用場景也是泛型。
Object
看下面源碼的注釋,Dart所有對象的基礎類。類似java中的Object
part of dart.core;
/**
* The base class for all Dart objects.
*
* Because Object is the root of the Dart class hierarchy,
* every other Dart class is a subclass of Object.
.....
*/
@pragma("vm:entry-point")
class Object {
}
那他與dynamic的區別是什么呢?
其實主要是一個是編譯時確定聲明的變量類型,一個是在運行時確定變量類型。
下面演示個例子,一看就了解了:
class Person {
var age;
}
class Girl extends Person {
void birth() {
print('生小孩');
}
}
void main() {
canBirth(Girl());
}
void canBirth(dynamic person) {
person.birth();
}
其中 最后一個scanBirth()方法的參數有好幾種寫法
因為birth()方法不是Person和Object對象的,所以我們調用編譯器會報錯。此時針對傳入的參數類型不確定,想要這個方法通用,并且不報錯。那么就可以用dynamic了,因為他是運行時才確定變量類型的,所以編譯器在編譯時并不會去檢查它的問題。
使用建議
個人建議:
- 在知道變量類型的情況下,盡量顯示的聲明變量類型。類似:String a ='hello'; 這樣能省去類型反推
- 使用Var的時候盡量在聲明時就初始化,這樣聲明后就確定了變量類型
- 盡量少用dynamic,因為使用它至少編譯器就不能幫你檢查出一些編譯時的錯誤
常量
常量就是聲明初始化后就不能改變,dart中主要通過final和const來修飾常量。
還有就是常量聲明的時候就必須初始化。
final
修飾的常量初始化后就不能更改了。它修飾的常量在運行時才生成。
const
const跟final的區別是 它修飾的常量是在編譯時就生成了。
所以正常情況下 const的不能在對象中使用,因為對象實例都是在運行時才創建。如果想在對象中使用const,則需要加static修飾,作為靜態常量使用,這樣就能保證其在編譯時就生成。
區別
- 常量生成時機不同,const是編譯時,final是運行時
- const定義的常量會傳遞到期子對象,其子元素也是不可修改的
- const不會重復定義相同對象
先代碼驗證下上面說的第二條
void main() {
final a =[1,2,3];
print(a);
a[1]=4;
print(a);
}
看下輸出結果:
下面我們看下const 修飾List會怎樣
void main() {
const a =[1,2,3];
print(a);
a[1]=4;
print(a);
}
看下輸出:
使用final修飾的List里面的參數是可以更改的,const修飾的不能更改
下面再使用const和final分別定義相同的對象,看看他們有沒有重復生成相同對象
void main() {
const a =[1,2,3];
const b =[1,2,3];
print(a.hashCode);
print(b.hashCode);
final c =[1,2,3];
final d =[1,2,3];
print(c.hashCode);
print(d.hashCode);
}
看下輸出結果
可以看到const聲明的對象內存中不會重復創建,而final修飾的會
基本數據類型
先講講基本的 numbers ,Strings,;booleans看看于其他語言的卻別
Numbers
在Dart中我們會發現long,float,short 這些數據類型是沒有的。Dart中只有兩種數據類型int和double。
Strings
Dart的字符串類型和Kotlin語言中的基本相同,比如說模板形式
void main() {
String s ='111';
print('this is a test : $s}');
}
可以在字符串中使用表達式,用法是這樣的: ${expression}。如果表達式是一個直接調用的,可以省略 {}。 如果表達式的結果為一個對象,則 Dart 會調用對象的 toString() 函數來獲取一個字符串。
還有使用 三個單引號可以寫成帶格式的字符串
void main() {
String s ='''
這是一個
有格式的字符串
還能換行o
''';
print('this is a test : $s}');
}
看下輸出樣式:
還有個比較牛逼的,比如我們在字符中加轉義字符,比如\n正常情況下輸出會換行,但是如果在字符串前加上小r,則會按原來的輸出,看下面例子:
void main() {
String s =' 測試下 \n 轉義字符';
String rs =r' 測試下 \n 轉義字符';
print(s);
print(rs);
}
輸出結果:
Booleans
這個跟java一樣,只有true和false兩個值,OC或者JS的同學可能不適應
后面還有容器的幾種類型 List ,Map 等單獨講。