版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載姓言。http://www.reibang.com/p/3d927a7bf020
轉(zhuǎn)載請標(biāo)明出處:
http://www.reibang.com/p/3d927a7bf020
本文出自 AWeiLoveAndroid的博客
Flutter系列博文鏈接 ↓:
工具安裝:
Flutter基礎(chǔ)篇:
- 谷歌Flutter1.0正式版發(fā)布
- Flutter基礎(chǔ)篇(1)-- 跨平臺開發(fā)框架和工具集錦
- Flutter基礎(chǔ)篇(2)-- 老司機(jī)用一篇博客帶你快速熟悉Dart語法
- Flutter基礎(chǔ)篇(3)-- Flutter基礎(chǔ)全面詳解
- Flutter基礎(chǔ)篇(4)-- Flutter填坑全面總結(jié)
- Flutter基礎(chǔ)篇(5)-- Flutter代碼模板,解放雙手,提高開發(fā)效率必備
- Flutter基礎(chǔ)篇(6)-- 水平和垂直布局詳解
- Flutter基礎(chǔ)篇(7)-- Flutter更新錯誤全面解決方案(圖文+視頻講解)
- Flutter基礎(chǔ)篇(8)-- Flutter for Web詳細(xì)介紹
- Flutter基礎(chǔ)篇(9)-- 手把手教你用Flutter實(shí)現(xiàn)Web頁面編寫
- Flutter1.9升級體驗(yàn)總結(jié)(Flutter Web 1.9最新版本填坑指南)
Flutter進(jìn)階篇:
- Flutter進(jìn)階篇(1)-- 手把手帶你快速上手調(diào)試Flutter項(xiàng)目
- Flutter進(jìn)階篇(2)-- Flutter路由詳解
- Flutter進(jìn)階篇(3)-- Flutter 的手勢(GestureDetector)分析詳解
- Flutter進(jìn)階篇(4)-- Flutter的Future異步詳解
- Flutter進(jìn)階篇(5)-- 使用Flutter創(chuàng)建插件詳解并發(fā)布到Pub庫
- Flutter進(jìn)階篇(6)-- PageStorageKey、PageStorageBucket和PageStorage使用詳解
- Flutter進(jìn)階篇(7)-- Flutter路由輕量級框架FRouter
Dart語法系列博文鏈接 ↓:
Dart語法基礎(chǔ)篇:
Dart語法進(jìn)階篇:
【前言】Dart語言是使用flutter框架開發(fā)時候必備的語言搜骡,flutter是一個跨平臺的框架,一套代碼就可以完美實(shí)現(xiàn)安卓和ios兩個平臺佑女,適配也很不錯记靡,Dart語言很友好,和java很類似团驱,學(xué)習(xí)成本也是很低的摸吠。所以這也是我推薦學(xué)習(xí)Dart語言的一個原因。
從本篇文章開始講解Dart語言的基本使用嚎花,我將會連續(xù)推出好幾篇文章詳解寸痢,希望幫助大家快速掌握Dart語言。
本文目錄:
一紊选、注釋
二啼止、關(guān)鍵字(56個)
三道逗、變量和常量
四、特殊數(shù)據(jù)類型
五献烦、運(yùn)算符
六憔辫、控制流程語句
七、異常
本文代碼同步發(fā)布在Github:
https://github.com/AweiLoveAndroid/Flutter-learning/tree/master/projects/dart_demo
怎么運(yùn)行代碼仿荆?
如果你使用IDEA或者Android Studio:
打開IDEA或者Android Studio,新建一個Flutter項(xiàng)目坏平,然后在test目錄運(yùn)行我的代碼拢操;或者里面去寫你自己的
dart
文件,然后右鍵run
就可以運(yùn)行了舶替。(注意:需要連接手機(jī)或者模擬器)令境。
如果你使用vscode:
打開vscode,執(zhí)行菜單欄
運(yùn)行
顾瞪,就可以了(確保只有一個dart文件舔庶,免得運(yùn)行的文件不是你想要的,就很尷尬了陈醒,vscode也可以設(shè)置默認(rèn)運(yùn)行的文件是哪個惕橙,但是新手不建議去設(shè)置,很麻煩钉跷。因?yàn)槟銈兿胱羁斓倪\(yùn)行效果弥鹦,所有建議只有一個dart文件是最好的)。
一爷辙、注釋
Dart的注釋分為3種:單行注釋彬坏、多行注釋、文檔注釋膝晾。
1栓始、單行注釋以
//
開頭。Dart編譯器會忽略//和行尾之間的所有內(nèi)容血当。
例如:// todo:待完成
2幻赚、多行注釋以
/*
開頭,以*/
結(jié)尾歹颓。介于/*
和*/
兩者之間的內(nèi)容會被編譯器忽略(除非該注釋是一個文檔注釋)坯屿。多行注釋可以嵌套。
例如:/* todo:待完成 */
3巍扛、文檔注釋以
///
或者/**
開頭领跛。可以通過dartdoc
命令導(dǎo)出文檔撤奸。
文檔注釋的使用吠昭,例如:/// todo:待完成
文檔的導(dǎo)出如圖所示:
導(dǎo)出的結(jié)果在我的工程根路徑的/doc/api/
文件夾里面喊括,如圖所示:
然后瀏覽器打開index.html
就可以看到文檔了。如圖所示:
二矢棚、關(guān)鍵字(60個)
5個上下文關(guān)鍵字(僅在特定位置具有含義郑什。它們在任何地方都是有效的標(biāo)識符)
關(guān)鍵字 | - | - | - |
---|---|---|---|
async | hide | on | show |
sync | - | - | - |
其中內(nèi)置標(biāo)志符有:(20個)
關(guān)鍵字 | - | - | - |
---|---|---|---|
abstract | as | covariant | defered |
dynamic | export | external | factory |
Function | get | implements | import |
interface | library | mixin | operator |
part | set | static | typedef |
Dart新增的,有限的保留字,支持異步功能的關(guān)鍵字有:(2個)
關(guān)鍵字 | - | - | - |
---|---|---|---|
await | yield |
33個保留字(不能使用保留字作為標(biāo)識符)
關(guān)鍵字 | - | - | - |
---|---|---|---|
assert | break | case | catch |
class | const | continue | default |
do | else | enum | extends |
false | final | finally | for |
if | in | is | new |
null | rethrow | return | super |
switch | this | throw | true |
try | var | void | while |
with | - | - | - |
跟java相比蒲肋,Dart特有的關(guān)鍵字有:(27個)
關(guān)鍵字 | - | - | - |
---|---|---|---|
as | async | await | covariant |
deferred | dynamic | export | external |
factory | Function | get | hide |
in | is | library | mixin |
on | operator | part | rethrow |
set | show | sync | typedef |
var | with | yield |
三蘑拯、變量和常量
(一)變量的聲明,可以使用 var兜粘、Object 或 dynamic 關(guān)鍵字申窘。
創(chuàng)建變量并初始化變量實(shí)例:
var name = '張三' ;
變量存儲引用。
- 使用Object或dynamic關(guān)鍵字
dynamic name = '張三';
調(diào)用的變量name包含對String值為“張三” 的對象的引用孔轴。
name推斷變量的類型是String剃法,但可以通過指定它來更改該類型。
如果對象不限于單一類型(沒有明確的類型)路鹰,請使用Object或dynamic關(guān)鍵字
Object name = '張三';
dynamic name = '李四';
- 顯式聲明將被推斷的類型
比如String,int等贷洲。
//可以使用String顯示聲明字符串類型
String name = '張三' ; //代替var name = '張三';
這個類型有很多,具體在下文有介紹晋柱。
(二)默認(rèn)值
未初始化的變量的初始值為null(包括數(shù)字)优构,因此數(shù)字、字符串都可以調(diào)用各種方法雁竞。
//測試 數(shù)字類型的初始值是什么?
int intDefaultValue;
// assert 是語言內(nèi)置的斷言函數(shù)俩块,僅在檢查模式下有效
// 在開發(fā)過程中, 除非條件為真浓领,否則會引發(fā)異常玉凯。(斷言失敗則程序立刻終止)
assert(intDefaultValue == null);
print(intDefaultValue);//打印結(jié)果為null,證明數(shù)字類型初始化值是null
(三)Final 和 Const的用法
如果您從未打算更改一個變量联贩,那么使用 final 或 const漫仆,不是var,也不是一個類型泪幌。
一個 final 變量只能被設(shè)置一次;const 變量是一個編譯時常量盲厌。(Const變量是隱式的final。)
final的頂級或類變量在第一次使用時被初始化祸泪。
- 1吗浩、被final或者const修飾的變量,變量類型可以省略没隘。
//可以省略String這個類型聲明
final name1 = "張三";
//final String name1 = "張三";
const name2 = "李四";
//const String name2 = "李四";
- 2懂扼、被 final 或 const 修飾的變量無法再去修改其值。
final name1 = "張三";
// 這樣寫,編譯器提示:a final variable, can only be set once
// 一個final變量阀湿,只能被設(shè)置一次赶熟。
//name1 = "zhangsan";
const name2 = "李四";
// 這樣寫,編譯器提示:Constant variables can't be assigned a value
// const常量不能賦值
// name2 = "lisi";
- 3陷嘴、注意:flnal 或者 const 不能和 var 同時使用
//這樣寫都會報錯
//final var name1 = "張三";
//const var name2 = "李四";
- 4映砖、常量如果是類級別的,請使用 static const
static const speed = 100;
- 5灾挨、常量的運(yùn)算
const speed = 100; //速度(km/h)
const double distance = 2.5 * speed; // 距離 = 速度 * 時間
final speed2 = 100; //速度(km/h)
final double distance2 = 2.5 * speed2; // 距離 = 速度 * 時間
- 6邑退、const關(guān)鍵字不只是聲明常數(shù)變量。您也可以使用它來創(chuàng)建常量值劳澄,以及聲明創(chuàng)建常量值的構(gòu)造函數(shù)瓜饥。 任何變量都可以有一個常量值。
// 注意: [] 創(chuàng)建的是一個空的list集合
// const []創(chuàng)建一個空的浴骂、不可變的列表(EIL)。
var varList = const []; // varList 當(dāng)前是一個EIL
final finalList = const []; // finalList一直是EIL
const constList = const []; // constList 是一個編譯時常量的EIL
// 可以更改非final,非const變量的值
// 即使它曾經(jīng)具有const值
varList = ["haha"];
// 不能更改final變量或const變量的值
// 這樣寫宪潮,編譯器提示:a final variable, can only be set once
// finalList = ["haha"];
// 這樣寫溯警,編譯器提示:Constant variables can't be assigned a value
// constList = ["haha"];
- 7、只要任何插值表達(dá)式是一個計算結(jié)果為null或數(shù)字狡相,字符串或布爾值的編譯時常量梯轻,那么文字字符串就是編譯時常量。(關(guān)于$表達(dá)式和不同的數(shù)據(jù)類型后面會講解尽棕。)
// 這些是常量字符串
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';
// 這些不是常量字符串
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = const [1, 2, 3];
const validConstString = '$aConstNum $aConstBool $aConstString';
//這樣用就會報錯:Const variables must be initialized with a constant value
// const常量必須用conat類型的值初始化喳挑。
// const invalidConstString = '$aNum $aBool $aString $aConstList';
四、特殊數(shù)據(jù)類型
Dart支持以下特殊類型:
numbers 數(shù)字
strings 字符串
booleans 布爾
lists list集合(也稱為數(shù)組)
maps map集合
runes 字符(用于在字符串中表示Unicode字符)
(一)num數(shù)字類型
num是數(shù)字類型的父類滔悉,有兩個子類 int
和 double
伊诵。
num類型包括基本的運(yùn)算符,如+,-,/和*回官,位運(yùn)算符曹宴,如>>,在int類中定義歉提。如果num和它的子類沒有你要找的東西笛坦,math庫可能會找到。比如你會發(fā)現(xiàn)abs(),ceil()和floor()等方法苔巨。
(1)int類型
int
表示整數(shù)版扩,int默認(rèn)是64位二進(jìn)制補(bǔ)碼整數(shù),int的取值不大于64位侄泽,具體取決于平臺礁芦。編譯為JavaScript時,整數(shù)僅限于valus悼尾,可以用雙精度浮點(diǎn)值精確表示宴偿∠嫔樱可用的整數(shù)值包括-253和253之間的所有整數(shù),以及一些幅度較大的整數(shù)窄刘。這包括一些大于2^63的整數(shù)窥妇。 因此,在編譯為JavaScript的Dart VM和Dart代碼之間娩践,int類中的運(yùn)算符和方法的行為有時會有所不同活翩。例如,當(dāng)編譯為JavaScript時翻伺,按位運(yùn)算符將其操作數(shù)截斷為32位整數(shù)材泄。
示例如下:
int intNum1 = 10 ;
print(intNum1);//結(jié)果是10
int intNum2 = 0xDEADBEEF ;
print(intNum2);//結(jié)果是3735928559
判斷一個int值需要多少bit(位),可以使用bitLength
吨岭,例如:
// bitLength 返回存儲此int整數(shù)所需的最小位數(shù)
int a1 = 1; // 占了1個bit 相當(dāng)于二進(jìn)制數(shù)字 00000000 00000001
int a2 = 12; // 占了4個bit 相當(dāng)于二進(jìn)制數(shù)字 00000000 00001100
int a3 = 123; // 占了7個bit 相當(dāng)于二進(jìn)制數(shù)字 00000000 01111011
int a4 = 1234; // 占了11個bit 相當(dāng)于二進(jìn)制數(shù)字 00000100 11010010
print('${a1.bitLength}'); // 1
print('${a2.bitLength}'); // 4
print('${a3.bitLength}'); // 7
print('${a4.bitLength}'); // 11
(2)double類型
Dart的double是IEEE 754標(biāo)準(zhǔn)中規(guī)定的64位浮點(diǎn)數(shù)拉宗。double的最大值是:1.7976931348623157e+308
,double類里面有一個常量maxFinite
辣辫,我們通過語句print(double. maxFinite)
可以得到double的最大值
旦事。
如果一個數(shù)字包含一個小數(shù),那么它就是一個double類型急灭。示例如下:
double doubleNum1 = 1.1;
print(doubleNum1); //結(jié)果是1.1
double doubleNum2 = 1.42e5;
print(doubleNum2); //結(jié)果是142000.0
(3)Dart2.1里面新增特性姐浮,當(dāng)double的值為int值時,int自動轉(zhuǎn)成double葬馋。
例如:double test = 12;//打印結(jié)果是12.0
(4)Dart2.1,int也有api轉(zhuǎn)成double卖鲤。
例如:
int test = 10;
print(test.toDouble()); // 結(jié)果是: 10.0
(5)Dart2.1,double也有api轉(zhuǎn)成int,會把小數(shù)點(diǎn)后面的全部去掉。
例如:
double test2 = 15.1;
double test3 = 15.1234;
print(test2.toInt());// 結(jié)果是15
print(test3.toInt());// 結(jié)果是15
(二)String字符串類型
Dart里面的String是一系列 UTF-16代碼單元畴嘶。
(1)您可以使用單引號或雙引號來創(chuàng)建一個字符串蛋逾。
String str1 = '單引號基本使用demo.';
String str2 = "雙引號基本使用demo.";
(2)單引號或者雙引號里面嵌套使用引號。
單引號里面嵌套單引號窗悯,或者//雙引號里面嵌套雙引號换怖,必須在前面加反斜杠。
// 單引號里面有單引號蟀瞧,必須在前面加反斜杠
String str3 = '單引號里面有單引號it\'s沉颂,必須在前面加反斜杠.';
//雙引號里面嵌套單引號(正常使用)
String str4 = "雙引號里面有單引號it's.";
//單引號里面嵌套雙引號(正常使用)
String str5 = '單引號里面有雙引號,"hello world"';
//雙引號里面嵌套雙引號悦污,必須在前面加反斜杠
String str6 = "雙引號里面有雙引號铸屉,\"hello world\"";
print(str3);// 雙引號里面有單引號it's,必須在前面加反斜杠
print(str4);// 雙引號里面有單引號it's.
print(str5);// 單引號里面有雙引號切端,hello world"
print(str6);//雙引號里面有雙引號彻坛,"hello world"
(3)多個字符串相鄰中間的空格問題:
除了單引號嵌套單引號或者雙引號嵌套雙引號不允許出現(xiàn)空串之外,其余的幾種情況都是可以運(yùn)行的。
示例如下:
這個會報錯
//String blankStr1 = 'hello''''world';
//這兩個運(yùn)行正常
String blankStr2 = 'hello'' ''world'; //結(jié)果: hello world
String blankStr3 = 'hello''_''world'; //結(jié)果: hello_world
// 這個會報錯
//String blankStr4 = "hello""""world";
這兩個運(yùn)行正常
String blankStr5 = "hello"" ""world"; //結(jié)果: hello world
String blankStr6 = "hello""_""world"; //結(jié)果: hello_world
單引號里面有雙引號昌屉,混合使用運(yùn)行正常
String blankStr7 = 'hello""""world'; //結(jié)果: hello""""world
String blankStr8 = 'hello"" ""world'; //結(jié)果: hello"" ""world
String blankStr9 = 'hello""_""world'; //結(jié)果: hello""_""world
雙引號里面有單引號钙蒙,混合使用運(yùn)行正常
String blankStr10 = "hello''''world"; //結(jié)果: hello''''world
String blankStr11 = "hello'' ''world"; //結(jié)果: hello'' ''world
String blankStr12 = "hello''_''world"; //結(jié)果: hello''_''world
(4)您可以使用相鄰字符串文字或+ 運(yùn)算符連接字符串:
- 直接把相鄰字符串寫在一起,就可以連接字符串了间驮。
String connectionStr1 = '字符串連接''甚至可以在''換行的時候進(jìn)行躬厌。';
print(connectionStr1);// 字符串連接甚至可以在換行的時候進(jìn)行。
- 用+把相鄰字符串連接起來竞帽。
String connectionStr2 = '字符串連接'+ '甚至可以在'+ '換行的時候進(jìn)行扛施。';
print(connectionStr2);// 字符串連接甚至可以在換行的時候進(jìn)行。
- 使用單引號或雙引號的三引號:
String connectionStr3 = '''
這是用單引號創(chuàng)建的
多行字符串屹篓。
''' ;
print(connectionStr3);
String connectionStr4 = """這是用雙引號創(chuàng)建的
多行字符串疙渣。""";
print(connectionStr4);
print(connectionStr3)輸出結(jié)果如下:
這是用單引號創(chuàng)建的
多行字符串。
print(connectionStr4)的輸出結(jié)果如下:
這是用雙引號創(chuàng)建的
多行字符串堆巧。
(5)關(guān)于轉(zhuǎn)義符號的使用
聲明raw字符串(前綴為r)
妄荔,在字符串前加字符r
,或者在\
前面再加一個\
谍肤,
可以避免“\”的轉(zhuǎn)義作用啦租,在正則表達(dá)式里特別有用。
舉例如下:
print(r"換行符:\n"); //這個結(jié)果是 換行符:\n
print("換行符:\\n"); //這個結(jié)果是 換行符:\n
print("換行符:\n"); //這個結(jié)果是 換行符:
(6)使用$
可以獲得字符串中的內(nèi)容谣沸,使用${表達(dá)式}
也可以將表達(dá)式的值放入字符串中。使用${表達(dá)式}
時可以使用字符串拼接笋颤,也可以使用String
類或者Object
里面的某些方法獲得相關(guān)字符串屬性乳附。
1、使用
$+字符串
var height = 48.0;
print('當(dāng)前標(biāo)題的高度是$height'); //當(dāng)前標(biāo)題的高度是48.0
2伴澄、使用$+字符串赋除,以及字符串拼接
String name = "張三";
print("$name"+"是我們的部門經(jīng)理"); // 張三是我們的部門經(jīng)理
3、這里使用了字符串的拼接非凌,以及使用了String類里面的toUpperCase()函數(shù)举农,把字母全部變成大寫。
String replaceStr = 'Android Studio';
assert('你知道' +
'${replaceStr.toUpperCase()}'
+ '最新版本是多少嗎敞嗡?' ==
'你知道ANDROID STUDIO最新版本是多少嗎颁糟?');
注:==
操作符測試兩個對象是否相等。assert
是斷言喉悴,如果條件為true棱貌,繼續(xù)進(jìn)行,否則拋出異常箕肃,中端操作婚脱。
(三)bool布爾類型
Dart表示布爾值的類型叫做bool
,它有兩個值,分別是:true
和false
障贸,它們都是編譯時常量错森。
Dart使用的是顯式的檢查值,檢查值的類型篮洁,如下所示:
// 檢查是否為空字符串
var emptyStr = '';
assert(emptyStr.isEmpty);
// 檢查是否小于等于0
var numberStr = 0;
assert(numberStr <= 0);
// 檢查是否為null
var nullStr;
assert(nullStr == null);
// 檢查是否為NaN
var value = 0 / 0;
assert(value.isNaN);
assert
是Dart語言里的的斷言函數(shù)
涩维,僅在Debug模式下有效
。
在開發(fā)過程中嘀粱, 除非條件為真激挪,否則會引發(fā)異常。(斷言失敗則程序立刻終止)锋叨。
(四)list集合垄分,也成為數(shù)組
在Dart中,數(shù)組是List對象娃磺,因此大多數(shù)人只是將它們稱為List薄湿。
以下是一個簡單的Dart的List:
創(chuàng)建一個int類型的list
List list = [10, 7, 23];
print(list);// 輸出結(jié)果 [10, 7, 23]
要創(chuàng)建一個編譯時常量const的list,示例如下:
List constantList = const[10,3,15];
print(constantList);// 輸出結(jié)果 [10, 3, 15]
注意事項(xiàng):
1.可以直接打印list包括list的元素偷卧,list也是一個對象豺瘤。但是java必須遍歷才能打印list,java若直接打印list听诸,結(jié)果是地址值坐求。
2.和java一樣list里面的元素必須保持類型一致,不一致就會報錯晌梨。
3.和java一樣list的角標(biāo)從0開始桥嗤。
Dart的list集合給我們提供了很多api,示例如下仔蝌,api太多就不逐個展示了:
操作 | 代碼 | 含義 | 輸出結(jié)果 |
---|---|---|---|
新增 | list.add(1);print(list); | 把數(shù)字1添加到list中泛领,默認(rèn)是添加到末尾 | [10, 7, 23, 1] |
移除 | list.remove(1);print(list); | 移除數(shù)字1 | [10, 7, 23] |
插入 | list.insert(0, 5);print(list); | 在索引為0的地方插入數(shù)字5 | [5, 10, 7, 23] |
查找某個索引的值 | int value = list.indexOf(10);print(value); | 查找10在list中的索引 | 1 |
判斷元素是否包含 | bool result = list.contains(5);print(result); | 查找list中是否包含數(shù)字5 | true |
(五)map集合
Dart中的map
是將鍵和值相關(guān)聯(lián)的對象。鍵和值都可以是任何類型的對象敛惊。每個鍵只出現(xiàn)一次渊鞋,但您可以多次使用相同的值。
(1)創(chuàng)建方式:
- 直接聲明瞧挤,用{}表示锡宋,里面寫key和value,每組鍵值對中間用逗號隔開特恬。
Map companys = {'first': '阿里巴巴', 'second': '騰訊', 'fifth': '百度'};
print(companys);//打印結(jié)果 {first: 阿里巴巴, second: 騰訊, fifth: 百度}
- 先聲明员辩,再去賦值。
Map companys1 = new Map();
companys1['first'] = '阿里巴巴';
companys1['second'] = '騰訊';
companys1['fifth'] = '百度';
print(companys1);
//打印結(jié)果 {first: 阿里巴巴, second: 騰訊, fifth: 百度}
- 要創(chuàng)建一個編譯時常量const的map鸵鸥,請?jiān)趍ap文字之前添加const:
final fruitConstantMap = const {2: 'apple',10: 'orange',18: 'banana'};
// 打印結(jié)果{second: 騰訊, fifth: 百度, 5: 華為}
(2)添加元素奠滑。格式: 變量名[key] = value,其中key可以是不同類型丹皱。
//添加一個新的元素,key為“5”宋税,value為“華為”
companys[5] = '華為';
print(companys);//打印結(jié)果 {first: 阿里巴巴, second: 騰訊, fifth: 百度, 5: 華為}
(3)修改元素摊崭。格式:變量名[key] = value
例如:把key為first的元素對應(yīng)的value改成 alibaba
companys['first'] = 'alibaba';
print(companys);//打印結(jié)果 {first: alibaba, second: 騰訊, fifth: 百度, 5: 華為}
(4)查詢元素
bool mapKey = companys.containsKey('second');
bool mapValue = companys.containsValue('百度');
print(mapKey); //結(jié)果為:true
print(mapValue); //結(jié)果為:true
(5)刪除元素.可以使用map的remove或者clear方法。
companys.remove('first');// 移除key為“first”的元素杰赛。
print(companys);// 打印結(jié)果{second: 騰訊, fifth: 百度, 5: 華為}
companys.clear();// 清空map集合的數(shù)據(jù)呢簸。
print(companys);// 打印結(jié)果{}
(6)關(guān)于map集合的小結(jié):
1.創(chuàng)建map有兩種方式。
2.map的key類型不一致也不會報錯乏屯。
3.添加元素的時候根时,會按照你添加元素的順序逐個加入到map里面,哪怕你的key不連續(xù)辰晕。
比如key分別是 1,2,4蛤迎,看起來有間隔,事實(shí)上添加到map的時候{1:value,2:value,4:value} 這種形式含友。
4.添加的元素的key如果是map里面某個key的英文替裆,照樣可以添加到map里面,
比如可以為3和key為three可以同時存在窘问。
5.map里面的key不能相同辆童,但是value可以相同,value可以為空字符串或者為null。
(六)runes 字符(用于在字符串中表示Unicode字符)
Unicode為世界上所有的書寫系統(tǒng)中使用的每個字母惠赫,數(shù)字和符號定義了唯一的數(shù)值把鉴。
Dart字符串是UTF-16代碼單元的序列,所以在字符串中表達(dá)32位Unicode值需要特殊的語法儿咱。
Unicode代碼點(diǎn)的常用方法是\uXXXX
庭砍,其中XXXX
是一個4位十六進(jìn)制值。
例如概疆,心形字符()是\u2665
逗威。要指定多于或少于4個十六進(jìn)制數(shù)字峰搪,請將該值放在大括號中岔冀。 例如,笑的表情符號是\u{1f600}
概耻。
String類有幾個屬性可以用來提取符文信息使套。 codeUnitAt和codeUnit屬性返回16位代碼單元。
以下示例說明了符文鞠柄,16位代碼單元和32位代碼點(diǎn)之間的關(guān)系侦高。
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
//使用String. fromCharCodes顯示字符圖形
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
五掰茶、運(yùn)算符
運(yùn)算符在每一種語言中都很常見暂筝,Dart的運(yùn)算符如下表所示:
我這里不詳細(xì)去講解每個運(yùn)算符的用法搓彻,我這里主要講一下Dart里面比較有代表性的以及有特點(diǎn)的一些運(yùn)算符相關(guān)用法。
(一)?.
像.
一樣暖混,但最左邊的操作數(shù)可以為空。
比如:Test?.funs
從表達(dá)式Test中選擇屬性funs庆揪,除非Test為空(當(dāng)Test為空時境析,Test?.funs
的值為空)。
class Test {
static int funs = 5;
Test() {
print('構(gòu)造函數(shù) Test');
}
static fun() {
print('Test fun函數(shù)');
}
}
void main(){
print(Test?.funs); // 打印5
}
(二)..
級聯(lián)符號..
級聯(lián)符號..
允許您在同一個對象上進(jìn)行一系列操作咆槽。 除了函數(shù)調(diào)用之外陈轿,還可以訪問同一對象上的字段。其實(shí)相當(dāng)于java的鏈?zhǔn)秸{(diào)用秦忿。
例如:
String s = (new StringBuffer()
..write('test1 ')
..write('test2 ')
..write('test3 ')
..write('test4 ')
..write('test5'))
.toString();
print(s); // test1 test2 test3 test4 test5
(三)?? 三目運(yùn)算符的一種形式麦射。
expr1 ?? expr2
表示如果expr1非空,則返回其值; 否則返回expr2的值灯谣。
//普通三元運(yùn)算符
int a = 10;
var values = a > 5 ? a : 0;
//??操作符
print('a ??=3 : ${a ??= 3}'); // 3
(四)~/ 除法潜秋,返回一個整數(shù)結(jié)果,其實(shí)就是取商酬屉。
小學(xué)都學(xué)過:被除數(shù) ÷ 除數(shù) = 商 ... 余數(shù)
半等,在Dart里面A ~/ B = C
,這個C就是商呐萨,這個語句相當(dāng)于Java里面的A / B = C
杀饵。Dart與java不同的是,Dart里面如果使用A / B = D
語句谬擦,這個結(jié)果計算出來的是真實(shí)的結(jié)果切距。示例如下:
var result1 = 15/7;
print(result1); // 結(jié)果是:2.142857...
var result2 = 15~/7;
print(result2); // 結(jié)果是:2
順便提一下取模
操作,在Dart里面A % B = E
惨远,這個E就是余數(shù)谜悟,%
符號表示取模
,例如:
var result3 = 15%7;
print(result3); // 結(jié)果是:1
(五)as北秽、is與is!
as
判斷屬于某種類型
is
如果對象具有指定的類型葡幸,則為true
is!
如果對象具有指定的類型,則為false
例如:
class Test {
static int funs = 5;
Test() {
print('構(gòu)造函數(shù) Test');
}
static fun() {
print('Test fun函數(shù)');
}
}
class Test2 extends Test {
Test2() {
print('構(gòu)造函數(shù) Test2');
}
void fun() {
print('Test2 fun函數(shù)');
}
}
void main(){
print(test2 is Test); // true
print(test is! Test2); // true
(test2 as Test2).fun(); // Test2 fun函數(shù)
// 相當(dāng)于
// if (test2 is Test) {
// test2.fun();
// }
六贺氓、控制流程語句
控制流程語句和Java語言差不多蔚叨,有這些語句:
(一)if else
if(條件語句){
內(nèi)容體
}else{
內(nèi)容體
}
(二)for循環(huán)
1.簡單for循環(huán)
for(初始值;判斷條件;循環(huán)后的語句){
內(nèi)容體
}
例如:
for(int i=0;i<10;i++){
print(i);
}
也可以通過for循環(huán)內(nèi)部的閉包獲取索引的值。
var array = [];
for(var i=0;i<10;i++){
array.add(()=> print(i));
}
2.使用foreach循環(huán)辙培,一般List和Set都可以使用foreach遍歷元素蔑水。
如果要迭代的對象是Iterable,或者你不想知道當(dāng)前的迭代次數(shù)扬蕊,可以使用foreach()
方法搀别。
var numbers = [1,2,3,4,5,6,7,8,9];
numbers.foreach((number)=> print(number));
3.使用for in循環(huán),一般List和Set使用for-in遍歷元素尾抑。
var list = [1,2,3];
for(var data in list){
print(data);
}
4.Dart的for循環(huán)里面可以使用標(biāo)記:(比較有特色的地方)
Dart的標(biāo)記:標(biāo)記是后面跟著冒號的標(biāo)識符
歇父。帶標(biāo)記的陳述是以標(biāo)記 L為前綴的陳述蒂培。帶標(biāo)簽的case子句是標(biāo)簽L前綴的switch語句中的case子句。標(biāo)簽的唯一作用是為“break”和“continue”聲明提供對象榜苫。
大多數(shù)此功能與其他語言類似毁渗,因此以下大部分內(nèi)容可能對讀者來說都很熟悉。Dart的switch聲明中處理continue是比較獨(dú)特的单刁,所以這一部分需要一點(diǎn)時間去閱讀和熟悉灸异。
- 1.循環(huán)(Loops)
標(biāo)簽最常用作break
和 continue
內(nèi)部循環(huán)。假設(shè)你有嵌套的循環(huán)羔飞,并要跳轉(zhuǎn)到break
或continue
到外部循環(huán)肺樟。如果沒有標(biāo)記,這不可能(輕松)實(shí)現(xiàn)逻淌。
以下示例使用continue 標(biāo)記名稱
從內(nèi)部循環(huán)直接跳轉(zhuǎn)到外部循環(huán)的下一輪循環(huán):
// 返回具有最小總和的內(nèi)部列表(正整數(shù))么伯。
/// Returns the inner list (of positive integers) with the smallest sum.
List<int> smallestSumList(List<List<int>> lists) {
var smallestSum = 0xFFFFFFFF; //已知list的總和較小。
var smallestList = null;
outer: // 這就是標(biāo)記
for (var innerList in lists) {
var sum = 0;
for (var element in innerList) {
assert(element >= 0);
sum += element;
// 無需繼續(xù)迭代內(nèi)部列表卡儒。它的總和已經(jīng)太高了田柔。
if (sum > smallestSum) continue outer; // continue 跳出到標(biāo)記處(outer)
}
smallestSum = sum;
smallestList = innerList;
}
return smallestList;
}
此函數(shù)在所有l(wèi)ist中運(yùn)行,但只要總和過高骨望,就會停止累加變量硬爆。
同理,可以使用break跳出到外部循環(huán):
// 計算第一個非空list
List<int> firstListWithNullValueList(List<List<int>> lists) {
var firstListWithNullValues = null;
outer:
for (var innerList in lists) {
for (var element in innerList) {
if (element == null) {
firstListWithNullValues = innerList;
break outer; // break 返回到標(biāo)記處
}
}
}
// 現(xiàn)在繼續(xù)正常的工作流程
if (firstListWithNullValues != null) {
// ...
}
return firstListWithNullValues;
}
- 2.跳出代碼塊
標(biāo)記也可以用于跳出代碼塊擎鸠。假設(shè)我們想要統(tǒng)一處理錯誤條件缀磕,但有多個條件(可能是深度嵌套)來揭示(reveal)錯誤。標(biāo)簽可以幫助構(gòu)建此代碼劣光。
void doSomethingWithA(A a) {
errorChecks: {
if (a.hasEntries) {
for (var entry in a.entries) {
if (entry is Bad) break errorChecks; // 跳出代碼塊
}
}
if (a.hasB) {
var b = new A.b();
if (b.inSomeBadState()) break errorChecks; // 跳出代碼塊
}
// 一些看起來都正常
use(a);
return;
}
// 錯誤的情況袜蚕,執(zhí)行這里的代碼:
print("something bad happened");
}
class A{
bool hasEntries = false;
bool hasB = true;
List<Bad> entries = [new Bad2(),new Bad2()];
A.b(){
}
bool inSomeBadState(){
return false;
}
}
void use(A a){}
abstract class Bad{}
class Bad1 extends Bad{}
class Bad2 extends Bad{}
對代碼塊的使用break指令,使得Dart繼續(xù)執(zhí)行塊之后的語句绢涡。從某個角度來看牲剃,它是一個結(jié)構(gòu)化的goto
,它只允許跳轉(zhuǎn)到當(dāng)前指令之后的嵌套較少的位置雄可。
雖然聲明標(biāo)簽在代碼塊中最有用凿傅,但它們可以用在在每個語句中。
例如滞项,foo: break foo;
是一個有效的聲明狭归。
請注意:continue
上面的循環(huán)可以通過將循環(huán)體包裝到帶標(biāo)記的代碼塊中并使用break來實(shí)現(xiàn)夭坪。
也就是說文判,以下兩個循環(huán)是等效的:
//以下兩種描述是等價的:
// 使用 continue
for (int i = 0; i < 10; i++) {
if (i.isEven) continue;
print(i);
}
// 使用 break.
for (int i = 0; i < 10; i++) {
labels: {
// isEven 當(dāng)且僅當(dāng)該整數(shù)為偶數(shù)時才返回true
if (i.isEven) break labels;
print(i);
}
}
- 3.Switch中的標(biāo)記(label)
標(biāo)記也可以用于switch內(nèi)部。
Switch中的標(biāo)記允許continue
使用其它的case
子句室梅。在最簡單的形式中戏仓,這可以作為一種方式來實(shí)現(xiàn)下一個子句:
void switchExample(int foo) {
switch (foo) {
case 0:
print("foo is 0");
break;
case 1:
print("foo is 1");
continue shared; // Continue使用在被標(biāo)記為shared的子句中
shared:
case 2:
print("foo is either 1 or 2");
break;
}
}
有趣的是, Dart沒有要求continue
的目標(biāo)子句是當(dāng)前case
子句之后的子句疚宇。
帶標(biāo)記的任何case
子句都是有效的目標(biāo)。這意味著赏殃,Dart的switch
語句實(shí)際上是狀態(tài)機(jī)(state machines)敷待。
以下示例演示了這種濫用,其中整個switch
實(shí)際上只是用作狀態(tài)機(jī)(state machines)仁热。
void main() {
runDog();
}
void runDog() {
int age = 0;
int hungry = 0;
int tired = 0;
bool seesSquirrel() => new Random().nextDouble() < 0.1;
bool seesMailman() => new Random().nextDouble() < 0.1;
switch (1) {
start:
case 0:
print("dog 方法已經(jīng)開始");
print('case 0 ==> age: $age');
print('case 0 ==> hungry: $hungry');
print('case 0 ==> tired: $tired');
continue doDogThings;
sleep:
case 1:
print("sleeping");
tired = 0;
age++;
if (age > 20) break;
print('case 1 ==> age: $age');
print('case 1 ==> hungry: $hungry');
print('case 1 ==> tired: $tired');
continue doDogThings;
doDogThings:
case 2:
if (hungry > 2) continue eat;
if (tired > 3) continue sleep;
if (seesSquirrel()) continue chase;
if (seesMailman()) continue bark;
print('case 2 ==> age: $age');
print('case 2 ==> hungry: $hungry');
print('case 2 ==> tired: $tired');
continue play;
chase:
case 3:
print("chasing");
hungry++;
tired++;
print('case 3 ==> age: $age');
print('case 3 ==> hungry: $hungry');
print('case 3 ==> tired: $tired');
continue doDogThings;
eat:
case 4:
print("eating");
hungry = 0;
print('case 4 ==> age: $age');
print('case 4 ==> hungry: $hungry');
print('case 4 ==> tired: $tired');
continue doDogThings;
bark:
case 5:
print("barking");
tired++;
print('case 5 ==> age: $age');
print('case 5 ==> hungry: $hungry');
print('case 5 ==> tired: $tired');
continue doDogThings;
play:
case 6:
print("playing");
tired++;
hungry++;
print('case 6 ==> age: $age');
print('case 6 ==> hungry: $hungry');
print('case 6 ==> tired: $tired');
continue doDogThings;
}
}
這個函數(shù)從一個switch子句跳到另一個子句榜揖,模擬了狗的生命。
在Dart中抗蠢,標(biāo)簽只允許在case子句中使用举哟,因此我必須添加一些case永遠(yuǎn)不會到達(dá)的行。
這個功能很酷迅矛,但很少使用妨猩。由于我們的編譯器增加了復(fù)雜性,我們經(jīng)常討論它的刪除秽褒。到目前為止壶硅,它已經(jīng)在我們的審查中幸存下來,但我們最終可能會簡化我們的規(guī)范并讓用戶自己添加一個while(true)
循環(huán)(帶有標(biāo)記)销斟。這個dog的示例可以重寫如下:
var state = 0;
loop:
while (true)
switch (state) {
case 0:
print("dog has started");
state = 2; continue;
case 1: // sleep.
print("sleeping");
tired = 0;
age++;
// The inevitable... :(
if (age > 20) break loop; // 跳出循環(huán)
// Wake up and do dog things.
state = 2; continue;
case 2: // doDogThings.
if (hungry > 2) { state = 4; continue; }
if (tired > 3) { state = 1; continue; }
if (seesSquirrel()) { state = 3; continue; }
...
如果狀態(tài)值被命名為常量庐椒,那么它將與原始版本一樣具有可讀性,但不需要switch
語句來支持狀態(tài)機(jī)蚂踊。
(三)while 和do while
while(判斷條件){
內(nèi)容體
}
do{
內(nèi)容體
} while(判斷條件);
while(a>5){
print(a);
}
do{
print(a);
} while(a>5);
(四)break continue
break 停止循環(huán)
while(a>5){
if(b>5){
print(a);
break;
}
}
continue 跳到下一個循環(huán)
while(a>5){
if(b<10){
print(b);
continue;
}
}
如果使用Iterable(list或者set)
扼睬,則可以使用下面這種方式:
// 第一個是滿足條件就進(jìn)入 第二個是foreach遍歷
arrays
.when((c)=>c.counts >=5)
.foreach((c)=>c.next());
(五)switch case
比較integer, string,編譯時常量 使用==。比較對象必須是同一個類的實(shí)例(不是其子類的實(shí)例)悴势,并且該類不能重寫==窗宇。枚舉類型在switch也可以運(yùn)行。
每一條非空case字子句以break結(jié)束特纤,也可以使用其他的方式結(jié)束:continue
,throw
或者return
军俊。
var command = 'OPEN';
switch (command) {
case 'CLOSED':
executeClosed();
break;
case 'PENDING':
executePending();
break;
case 'APPROVED':
executeApproved();
break;
case 'DENIED':
executeDenied();
break;
case 'OPEN':
executeOpen();
break;
default:
executeUnknown();
}
(六)assert
如果布爾條件為false,則使用assert語句來中斷正常執(zhí)行捧存。例如:
// 確保變量具有非空值
assert(text != null);
// 確保值小于100
assert(number < 100);
// 確保這是一個 https 網(wǎng)址
assert(urlString.startsWith('https'));
要將消息附加到斷言粪躬,請?zhí)砑右粋€字符串作為第二個參數(shù)。
assert(urlString.startsWith('https'),'URL ($urlString) should start with "https".');
上例中assert
的第一個參數(shù)可以是任何解析為布爾值的表達(dá)式昔穴。如果表達(dá)式的值為true镰官,則斷言成功并繼續(xù)執(zhí)行。如果為false吗货,則斷言失敗并拋出異常
七泳唠、異常
Dart代碼可以拋出并捕獲異常。Exception是指示發(fā)生意外事件的錯誤宙搬。如果未捕獲異常笨腥,則會暫停引發(fā)異常的isolate 拓哺,并且通常會終止isolate及其程序。
與Java相比脖母,Dart的所有異常都是未經(jīng)檢查的異常士鸥。方法不會聲明它們可能引發(fā)的異常,并且您不需要捕獲任何異常谆级。
Dart提供了Exception
和Error
類型烤礁,以及許多預(yù)定義的子類型。當(dāng)然肥照,您可以定義自己的Exception鸽凶。但是,Dart程序可以拋出任何非null對象建峭,作為Exception(不僅僅是Exception和Error對象)玻侥。
(一)throw
以下是拋出或引發(fā)異常的示例:
throw FormatException('Expected at least 1 section');
你也可以拋出任意對象,例如:throw '格式不正確!';
通常在開發(fā)中會拋出Error或者Exception類型亿蒸。
因?yàn)閽伋霎惓J且粋€表達(dá)式凑兰,所以可以在=>語句中以及允許表達(dá)式的任何其他地方拋出異常:
void distanceTo(Point other) => throw UnimplementedError();
(二)try catch
捕獲或捕獲異常會阻止異常傳遞(除非您重新拋出異常)。捕獲異常使您有機(jī)會處理它:
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
要處理可能拋出多種類型異常的代碼边锁,可以指定多個catch子句
姑食。與拋出對象的類型匹配的第一個catch子句處理異常。如果catch子句未指定類型茅坛,則該子句可以處理任何類型的拋出對象音半。
您可以使用on或catch
或兩者兼而有之
。使用on時需要指定異常類型
贡蓖。使用catch時曹鸠,你的異常處理程序需要異常對象。
示例:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e');
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
您可以指定一個或兩個參數(shù)catch()斥铺。第一個是拋出的異常彻桃,第二個是堆棧跟蹤(StackTrace對象)。
示例:
try {
// ···
} on Exception catch (e) {
print('Exception details:\n $e');
} catch (e, s) {
print('Exception details:\n $e');
print('Stack trace:\n $s');
}
要部分處理異常晾蜘,同時允許它傳遞邻眷,請使用rethrow關(guān)鍵字。
示例:
void misbehave() {
try {
dynamic foo = true;
print(foo++); // 運(yùn)行時異常
} catch (e) {
print('misbehave() partially handled ${e.runtimeType}.');
rethrow; // 允許調(diào)用者查看exception.
}
}
void main() {
try {
misbehave();
} catch (e) {
print('main() finished handling ${e.runtimeType}.');
}
}
(三)finally
無論是否拋出異常剔交,要確保某些代碼運(yùn)行肆饶,請使用finally
子句。如果沒有catch子句匹配該異常岖常,則在finally子句運(yùn)行后傳遞異常驯镊。
示例:
try {
breedMoreLlamas();
} finally {
// 即使拋出異常 也會執(zhí)行這句代碼.
cleanLlamaStalls();
}
該finally子句在任何匹配的catch子句之后運(yùn)行:
try {
breedMoreLlamas();
} catch (e) {
// 首先會處理異常
print('Error: $e');
} finally {
// 然后執(zhí)行這句語句
cleanLlamaStalls();
}