1. 定義和使用變量javascript
儘管Dart是靜態語言,但仍然擁有動態特性。因此定義變量也有以下2種方式。php
使用數據類型定義變量java
使用var定義變量nginx
在Dart語言中,數據類型放在變量前面,格式以下:數組
數據類型 變量名;
在Dart語言中,每條語句後面必須跟分號(;),因此在定義變量時後面也要加分號。以下面的代碼定義了一個整數類型的變量和一個字符串類型的變量。微信
int num; // 整數類型的變量String s; // 字符串類型的變量
在定義變量時能夠同時爲變量賦值,也稱爲初始化,因此能夠用下面的代碼爲num和s賦值。app
int num = 20;String s = "hello world";
若是在定義變量時指定了數據類型,那麼就意味着變量的數據類型不能夠改變,例如,上面代碼中已經將num變量定義爲int類型,那麼num就永遠是int類型,不能夠爲該變量賦其餘類型的值。函數
因爲Dart語言中一切皆爲對象,因此若是在定義變量時沒有爲其初始化,那麼變量的默認值就是null。ui
另一種定義變量的方法是使用var關鍵字,代碼以下:url
var num = 20; // num被自動識別爲int類型的變量var value; // 因爲value在定義時沒有被初始化,因此value的數據類型是dynamic
上面兩行代碼分別使用var定義了兩個變量,但這兩個變量是有區別的。num變量因爲在定義時已經初始化了,因此num的數據類型會根據初始化的值自動識別,很顯然,20屬於int類型的值,因此num變量的數據類型就是int,並且與直接指定變量的數據類型同樣,num變量的數據類型將永久固定,後期是不能夠改變的。但value就不一樣了。因爲在定義value變量是沒有爲其初始化,也沒有指定數據類型,因此value的數據類型就被識別爲dynamic。這是Dart語言中的一種特殊數據類型,有了dynmaic,Dart就能夠很容易動態化。若是Dart編譯器遇到dynamic數據類型的變量,就不會對該變量進行任何類型檢測,至關於在JavaScript中使用變量同樣。不過若是調用了變量中不存在的成員(如屬性、方法等),在運行時會拋出異常。但dynamic提供瞭解決方案來避免這種異常,關於dynamic的詳細用法,在後面的章節會深刻介紹。
綜上所述,在Dart語言中,若是爲變量指定了數據類型,那麼變量就是靜態的,變量的數據類型永遠不能夠改變。若是變量的數據類型是dynamic,變量就是動態的。能夠爲該變量賦任何值。讓變量是靜態類型和動態類型分別由以下2種方式。
(1)靜態類型的變量
(1)顯式指定變量的數據類型,如int num;
(2)使用var定義變量,但在定義時初始化了變量,而且初始化變量的表達式不是dynamic類型。如var value = 20;
(2)動態類型的變量
使用var定義變量,並且在定義時未初始化變量。即便在後面爲變量賦了值,該變量仍然是dynamic類型的變量,如var value;
直接使用dynamic類型定義變量,如dynamic value;
本例演示了各類定義和使用變量的方式。
void main() { var name = "Bill"; // String類型變量 var value1 = 20; // int類型變量 int value2 = 30; // int類型變量 print(name); // 輸出Bill print(value1 + value2); // 輸出50 // 在Dart中一切都是對象,若是未初始化變量,變量的默認值就是null var value; // dynamic類型變量 int value3; // int類型變量 print(value); // 輸出null print(value3); // 輸出null String s; // 條件爲true if(s == null) { print("NULL"); }}
運行結果如圖1所示。
圖1定義和使用變量
2. 定義和使用常量
常量的定義方式與變量相似,只是須要使用const或final來定義常量。這兩個關鍵字至關於var對於變量的做用。下面是定義常量的基本方法。
final username = '李寧';const value = 1234;
在上面的代碼中,username和value是兩個常量,這兩個常量都沒有指定數據類型,不過因爲Dart語言要求常量必須在定義時初始化,因此全部定義的常量右側都會有一個初始化表達式,Dart編譯器會利用這個初始化表達式自動識別常量的數據類型。上面的例子中,username被識別爲String類型,value被識別爲int類型。
在定義常量時,也能夠顯式地爲其指定數據類型,代碼以下:
final String username = '李寧';const int value = 1234;
常量只能在定義時被初始化一次,不能在使用的過程當中賦值,因此下面的代碼是沒法編譯經過的。
username = '小明'; // 沒法給常量賦值,會出現編譯錯誤value = 4321; // 沒法給常量賦值,會出現編譯錯誤
那麼可能有的讀者會問,爲何定義常量要提供兩個關鍵字(const和final)呢?其實用這兩個關鍵字定義常量是有必定區別的。const是編譯時常量,而final是運行時常量。下面解釋一下什麼是編譯時常量,什麼是運行時常量。
編譯時常量:在Dart編譯器在編譯時會自動計算的常量,也就是說,無論常量的初始化時是一個值,仍是一個表達式,Dart編譯器都會將這個表達式計算成一個值。換句話說,這種常量無論初始化表達式是什麼,最終在內存中都是一個值。因此使用這種常量的效率特別高。
運行時常量:這種常量與變量相似,都會在每次使用常量時現技術常量初始化表達式的值,因此使用這種變量的效率較低。
既然編譯時常量在編譯代碼時會自動計算初始化表達式的值,那麼就意味着初始化表達式中的每個部分都必須在編譯時能夠得到具體的值。這就要求初始化表達式只能由值或其餘編譯時常量組成,不能由變量、運行時常量、函數組成。由於這些元素的值只有在程序運行時才能夠得到,而編譯時程序尚未運行,因此編譯時常量的初始化表達式不能由這些元素組成。
運行時常量的初始化表達式與變量的初始化表達式相似。
const和final的用法見下面的代碼。
const m = 20; // 編譯時常量const n = m + 30; // 編譯時常量final k = 40; // 運行時常量const w = k + 20; // 編譯錯誤,由於編譯時常量的初始化表達式只能由值和編譯時常量組成
3. 常量列表和列表常量
常量一樣也能夠用來定義列表。列表是Dart語言的內建數據類型,關於列表的詳細用法,會在後面的章節深刻介紹。本節只介紹使用final和const定義常量列表和列表常量。那麼這兩個列表有什麼區別呢?
常量列表:指列表中的每個元素都是常量,但列表自己多是一個常量,也多是一個變量。若是列表自己是一個變量,而列表元素都是常量,那麼就意味着不能修改列表的每個元素,但能夠再次爲列表變量賦值。
列表常量:指列表自己是一個常量。對於這樣的常量,列表中每個元素一樣也是一個常量。對於這種列表,列表自己與列表中的元素都不能夠改變。
在定義常量列表時,能夠在列表初始化值前面加const(不能使用final),也能夠不加。在定義列表常量時,可使用const,也可使用final。
本例演示了常量的定義和使用方法,以及常量列表和列表常量的定義與使用方法。
void main() { final username = '李寧'; const password = '1234'; // username = "abc"; // 編譯錯誤,不能爲常量賦值 // password = "1234"; // 編譯錯誤,不能爲常量賦值 const n = 20; final x1 = n *2 + 20; const x2 = n * 2 + 20; // 自動計算,x2實際上存儲的是60 const x3 = x2 * 2; print(x2); print(x3); var values1 = const [1,2,3]; // 定義一個常量列表 print(values1); values1 = [5,6,7]; // 列表自己是變量,因此能夠從新設置列表的值 print(values1[1]); // values[1] = 4; // 不會有編譯錯誤,但會拋出運行時異常 final values2 = const["a","b"]; // 定義列表常量 // values2 = ["b","c"]; // 編譯錯誤 // values2[1] = "x"; // 運行時錯誤 const values3 = [5,6]; // 定義一個列表常量 // values3[1] = 4; // 運行時錯誤}
運行結果如圖2所示。
圖2常量與列表
往期回顧:
同時搞定Android和iOS的Dart語言(1):Dart初探
本文分享自微信公衆號 - 極客起源(geekculture)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。