? 學(xué)習(xí)一門新的語言,我們可以以自己現(xiàn)有的熟悉的語言來類比,比如我們非常熟悉Java,那么剩下的就是需要掌握與Java不同的Dart語法,剩下的就需要靠自己多寫多看來慢慢熟悉。
? 國際慣例,使用Dart完成一個:"Hello,World!"
變量
? 變量是一個引用,未初始化的變量值是null。
Object name1 = '顯示字符串';
var name2 = '顯示字符串';
dynamic name3 = '顯示字符串';
print('$name1 $name2 $name3');
//變量是一個引用,上面的name1、name2與name3的變量都引用了 一個內(nèi)容為 “顯示字符串” 的 String 對象。
? 可以用Object、var與dynamic聲明的變量賦任何類型的值,但是背后的原理卻是非常不同。
1、Object: 與Java一樣Object是所有類的基類,Object聲明的變量可以是任意類型。(在 Dart 中 甚至連 數(shù)字、方法和 null 都是對象,比如int。)
Object a = 1;
a = "a";
2、var: 聲明的變量在賦值的那一刻,決定了它是什么類型。
//a已經(jīng)確定為num,不能再賦值字符串,編譯錯誤
var a = 1;
a = "a";
//正確
var b;
b = 1;
b = "a";
3、dynamic: 不是在編譯時候確定實際類型的, 而是在運行時。dynamic聲明的變量行為與Object一樣
沒有初始化的變量自動獲取一個默認(rèn)值為
null(類型為數(shù)字的 變量如何沒有初始化其值也是 null)。在聲明變量的時候,也可以選擇加上具體 類型:int a = 1;
對于局部變量,按照Dart代碼風(fēng)格推薦,使用
var而不是具體的類型來定義局部變量。
final與const
? 如果不打算改變一個變量,可以使用final和const,它們可以替代任何類型,只能在聲明時初始化,且不能改變。
const a = 1;
final b =1;
final int c = 1;
const int d = 1;
? final與const從使用上根本看不出區(qū)別,但是final是運行時常量,而const是編譯器常量,它的值在編譯期就可以確定,編譯時常量能夠讓代碼運行的更高效。
//正確,已經(jīng)確定的值
const a = 1;
const b = a + 1;
//錯誤,final不能在編譯時確定值,因此const也不能確定值
final a = 1;
const c = a + 1;
類的變量可以為 final 但是不能是 const 。如果 const 變量在類中,需要定義為static const靜態(tài)常量
內(nèi)置的類型
與Java的八大內(nèi)置基本數(shù)據(jù)類型不同,Dart 內(nèi)置支持下面這些類型:
- numbers
- strings
- booleans
- lists (也被稱之為 arrays)
- maps
- runes (用于在字符串中表示 Unicode 字符)
- symbols
Numbers(數(shù)值)
num是數(shù)字類型的父類,有兩個子類int和 double。
Strings(字符串)
? Dart 字符串是 UTF-16 編碼的字符序列。 可以使用單引號或者雙引號來創(chuàng)建字符串,單引號和雙引號可以嵌套使用,否則需要使用\進(jìn)行轉(zhuǎn)義。字符串中也可以引用變量與表達(dá)式。
var name = 'yeyu';
//如果插入一個簡單的標(biāo)識符,而后面沒有緊跟更多的字母數(shù)字文本,那么{}應(yīng)該被省略。
var a = "my name is $name!";
var b = "my name is ${name.toUpperCase()}!";
? 與Java一樣可以使用 + 操作符來把拼接字符串,也可以把多個 字符串放到一起來實現(xiàn)同樣的功能:
var a = "my name is " "yeyu";
? 使用三個單引號或者雙引號可以 創(chuàng)建多行字符串對象
var s1 = '''
You can create
multi-line strings like this one.
''';
var s2 = """This is also a
multi-line string.""";
? 提供一個 r 前綴可以創(chuàng)建一個 “原始 raw” 字符串
print(r"換行符:\n"); // 換行符:\n r:不需要轉(zhuǎn)義
print("換行符:\\n"); // 換行符:\n
Booleans(布爾值)
? Dart 有一個名字為 bool 的類型。 只有兩個對象是布爾類型的:true 和 false 。這一點和Java沒有太大的區(qū)別。
Lists(列表)
? 幾乎所有編程語言中最常見的集合可能是數(shù)組或有序?qū)ο蠼M。在Dart中,數(shù)組就是List對象。對List進(jìn)行遍歷也和Java一樣。
var list = [1, 2, 3];
//Lists 的下標(biāo)索引從 0 開始,第一個元素的索引是 0. list.length - 1 是最后一個元素的索引
print(list[list.length-1]);
//修改元素
list[0] = 2;
//使用new(實際上new可以省去)
var list = new List(1);
list[0] = 2;
//在 list 字面量之前添加 const 關(guān)鍵字,可以 定義一個不變的 list 對象(編譯時常量)
var list = const [1,2,3];
i.add(2); ///錯誤,list不可變
Maps(映射集合)
? Map:鍵值對相關(guān)的對象。 鍵和值可以是任何類型的對象。每個 鍵 只出現(xiàn)一次, 而一個值則可以出現(xiàn)多次。
//直接聲明,用{}表示,里面寫key和value,每組鍵值對中間用逗號隔開
var companys = {'a': '阿里巴巴', 't': '騰訊', 'b': '百度'};
var companys2 = new Map();
companys2['a'] = '阿里巴巴';
companys2['t'] = '騰訊';
companys2['b'] = '百度';
//添加元素
companys['j'] = '京東';
//獲取與修改元素
var c = companys['c']; ///沒有對應(yīng)的key返回null
companys['a'] = 'alibaba';
? 與List一樣,在 map字面量之前添加 const 關(guān)鍵字,可以 定義一個 編譯時常量 的 map
Runes(用于在字符串中表示Unicode字符)
? Unicode為世界上所有的書寫系統(tǒng)中使用的每個字母,數(shù)字和符號定義了唯一的數(shù)值。 Dart 字符串是 UTF-16 位代碼單元字符序列, 所以在字符串中表達(dá) 32位 Unicode 值需要 新的語法。Runes就是UTF-32字符集的string 對象。
? 表達(dá)Unicode代碼點的常用方法是\uXXXX,其中XXXX是4位十六進(jìn)制值。要指定多于或少于4個十六進(jìn)制數(shù)字,需要將值放在大括號中。
var clapping = '\u{1f44f}'; ///5個16進(jìn)制 需要使用{}
print(clapping);//??
//獲得 16位代碼單元
print(clapping.codeUnits); //[55357, 56399]
//獲得unicode代碼
print(clapping.runes.toList()); //[128079]
//fromCharCode 根據(jù)字符碼創(chuàng)建字符串
print( String.fromCharCode(128079));
print( String.fromCharCodes(clapping.runes));
print( String.fromCharCodes([55357, 56399]));
print( String.fromCharCode(0x1f44f));
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(String.fromCharCodes(input));
實際上在Flutter開發(fā)中Runes與下一個Symbols可能永遠(yuǎn)也不會用到。
Symbols
? 操作符標(biāo)識符,可以看作C中的宏。表示編譯時的一個常量
var i = #A; //常量
main() {
print(i);
switch(i){
case #A:
print("A");
break;
case #B:
print("B");
break;
}
var b = new Symbol("b");
print(#b == b); ///true
}
操作符
常見的操作符就沒什么可說的了,主要來看看Java所沒有的。
類型判定操作符
as、 is、 和 is! 操作符是在運行時判定對象 類型的操作符
| 操作符 | 解釋 |
|---|---|
as |
類型轉(zhuǎn)換 |
is |
如果對象是指定的類型返回 True |
is! |
如果對象是指定的類型返回 False |
as 操作符把對象轉(zhuǎn)換為特定的類型,但是如果無法完成轉(zhuǎn)換則會拋出一個異常
is 和Java中的 instanceof 相同
賦值操作符
=、+=、\=、*=這些不必多說,還有一個 ??= 操作符用來指定 值為 null 的變量的值
b ??= value; // 如果 b 是 null,則 value 賦值給 b;
// 如果不是 null,則 b 的值保持不變
條件表達(dá)式
Dart 有兩個特殊的操作符可以用來替代 if-else 語句:
-
condition ? expr1 : expr2如果 condition 是 true,執(zhí)行 expr1 (并返回執(zhí)行的結(jié)果); 否則執(zhí)行 expr2 并返回其結(jié)果。
-
expr1 ?? expr2如果 expr1 不為null,返回其值; 否則執(zhí)行 expr2 并返回其結(jié)果。
級聯(lián)操作符
? 級聯(lián)操作符 (..) 可以在同一個對象上 連續(xù)調(diào)用多個函數(shù)以及訪問成員變量。 使用級聯(lián)操作符可以避免創(chuàng)建 臨時變量, 并且寫出來的代碼看起來 更加流暢:
//StringBuffer write就是Java的append
var sb = new StringBuffer();
sb..write('foo')..write('bar');
安全操作符
? Dart提供了 ?.操作符。左邊的操作對象 如果 為 null 則返回 null
String sb;
//空指針
print(sb.length);
print(sb?.length);