變量
變量聲明
1. 通過var
-
var name='Bob'
-
變量存儲的是對象的引用
-
變量存儲的是對象的引用,這裏的變量
name
存儲了一個String
類型的引用,Bob
則hi這個String
類型的引用的值 -
var聲明變量後如果沒有初始值,可以變成任何類型
-
var a; a="name"; a=123; a=true; //這樣沒有錯誤編譯時根據值來推斷類型
-
如果有初始值類型將被鎖定,不可改變數據類型
-
var name="Bob"; name=1000 // 這樣是錯誤的
-
-
name變量的類型被推斷爲String(Dart支持類型推斷)
2.指定類型
可以通過指定類型的方式來改變變量類型,如果對象不確定單個類型可以指定爲object或者dynamic
object
-
動態任意類型類型可變, 編譯階段檢查
-
Object object = "hello world"; print(object.runtimeType); //String print(object); //hello world object = 1; print(object.runtimeType); //int 說明類型是可變的 print(object); //1 //object.foo();靜態檢查會運行報錯會報錯 object.foo();
-
dynamic
-
動態任意類型,編譯階段不檢查運行階段檢查
-
dynamic mic = "hello world"; //編譯時不會揣測數據類型,但是運行時會推斷 print(mic.runtimeType); //String print(mic); //hello world //但是這樣的壞處就是會讓dart的語法檢查失效,所以有可能會造成混亂而不報錯 //所以不要直接使用dynamic mic.foo(); //通過它定義的變量會關閉類型檢查,這段代碼靜態類型檢查不會報錯,但是運行時會crash,因爲mic並沒有foo()方法, // 所以建議大家在編程時不要直接使用dynamic mic = 1; print(mic.runtimeType); //int 說明類型是可變的 print(mic); //1
-
3.顯式聲明可以推斷出的類型
-
String name='Bob';
4 . 通過final const 聲明不可變變量 下面有介紹
final ,const(常量)
使用過程中從來不會被修改的變量(可以稱爲常量),
可以使用final或const
Fianl變量的值只能被設置一次;final定義的常量可以用變量來初始化
Const變量在編譯階段就已經固定(Const 時隱式的final類型最高級 final 變量)最高級 final 變量或類變量在第一次使用時被初始化。(編譯時常量)
實例變量可以是
final
類型但不能是const
類型。 必須在構造函數體執行之前初始化 final 實例變量 —— 在變量聲明中,參數構造函數中或構造函數的初始化列表中進行初始化
var a; //final定義的常量可以用變量來初始化 final b=a;// 可以 final time = new DateTime.now(); //Ok // const定義的是編譯時常量,只能用編譯時常量來初始化 const c=a;// error const time = new DateTime.now(); //Error,new DateTime.now()不是const常量
Const 關鍵字不僅可以用於聲明常量變量。 還可以用來創建常量值,以及聲明創建常量值的構造函數。 任何變量都可以擁有常量值。
來點簡單的描述
final const 用來修飾不可變變量
- 啥不可變變量 就是常量。。
聲明必須賦值
區別
final 可以賦值爲變量 在運行前確定其值即可
const 賦值必須爲編譯時常量,因爲其編譯時會檢測
顧名思義編譯時常量只有編譯前可以改變值 編譯時無法改變
比如將其作爲參數傳遞 參考後面的 可選參數示例
示例
//可傳遞List map 作爲可選參數 //const 表示編譯時常量 故名思意 只有編譯前可以改變值 編譯後無法改變 void doStuff( {List<int> list = const [1, 2, 3], Map<String, String> gifts = const { 'first': 'paper', 'secend': 'cotton', 'third': 'leather' }}) { print('list: $list'); print('gifts:$gifts'); } //調用 注意看 const list 是不是發生了改變 默認值變了 List<int> list = [4, 5, 6]; Map<String, String> map = { 'one': 'param1', 'two': 'param2', 'three': 'param3' }; doStuff(list: list, gifts: map);
默認值
未初始化的變量默認值是
null
。即使變量是數字 類型默認值也是 null,因爲在 Dart 中一切都是對象,數字類型 也不例外。
靜態變量
通過static 修飾 類級別變量 全局類名調用訪問
類型
Number
Dart 語言的 Number 有兩種類型:
int
-
var x = 1;
double
-
var y = 1.1; var exponents = 1.42e5; //從 Dart 2.1 開始,必要的時候 int 字面量會自動轉換成 double 類型。 double z = 1; // 相當於 double z = 1.0.
類型轉換
-
// String -> int var one = int.parse('1'); assert(one == 1); // String -> double var onePointOne = double.parse('1.1'); assert(onePointOne == 1.1); // int -> String String oneAsString = 1.toString(); assert(oneAsString == '1'); // double -> String String piAsString = 3.14159.toStringAsFixed(2); assert(piAsString == '3.14');
String
Dart 字符串是一組 UTF-16 單元序列。
-
字符串通過單引號或者雙引號創建。
-
String name="Bob"; String name='Bob';
-
-
單引號或者雙引號裏嵌套使用引號
-
String msg="hello 'Bob' ,How are you"; String msg2 = 'Hello "Bob" ,How are you'; print(msg); print(msg2); //Hello 'Bob' ,How are you //Hello 'Bob' ,How are you
-
-
字符串可以通過
${
expression
}
的方式內嵌表達式。 如果表達式是一個標識符,則 {} 可以省略。-
String name = "Bob"; String msg = "Hello '$name' ,How are you"; String msg2 = 'Hello "${name.toUpperCase()}" ,How are you'; print(msg); print(msg2); //Hello 'Bob' ,How are you //Hello "BOB" ,How are you
-
-
使用連續三個單引號或者三個雙引號實現多行字符串對象的創建:
-
var msg3=''' hello Bob How are you '''; print(msg3); //hello Bob 保留定義字符串格式 // How are you
-
-
使用r 前綴創建原始字符串
-
原始(raw)字符串,在原始(raw)字符串中,字符表示的就是其本身,轉義字符會失去意義。
\n
不是換行,而是普通的\
和n
字符。 -
var s = r"In a raw string, even \n isn't special."; print(s); //In a raw string, even \n isn't special.
-
Boolean
Dart 使用
bool
類型表示布爾值。只有bool 類型的值是true 才被認爲是true。 Dart 只有字面量true
andfalse
是布爾類型, 這兩個對象都是編譯時常量。Dart 的類型安全意味着不能使用
if (*nonbooleanValue*)
或者assert (*nonbooleanValue*)
。 而是應該像下面這樣,明確的進行值檢查:
// 檢查是否爲空字符串 var fullName = ''; assert(fullName.isEmpty); if (fullName.isEmpty) { print('fullName null'); } // 檢查0 var hitPoints = 0; assert(hitPoints <= 0); // 檢查是否爲null var unicorn; assert(unicorn == null); // 檢查是否爲NaN var iMeantToDoThis = 0 / 0; assert(iMeantToDoThis.isNaN);
List
-
Array 就是 List 對象, 通常稱之爲 List 。
-
注意事項
-
可以直接打印list包括list的元素,list也是一個對象。但是java必須遍歷才能打印list,直接打印是地址值
-
和java一樣list裏面的元素必須保持類型一致,不一致就會報錯。
-
和java一樣list的下標從0開始。
-
List list = [10, 7, 23]; // 輸出[10, 7, 23] print(list); // 類型推斷爲int類型的list 存放其他類型將出錯 //list.add("1")//error
-
-
如果集合裏面有多個相同的元素“X”, 只會刪除集合中第一個該元素
-
非元素累固定型List 可以存放多種類型格式數據
-
List listMore = new List(); listMore.add('1'); //String listMore.add(1); //int listMore.add(1.111); //double listMore.add(true); //boolean print(listMore);
-
-
使用List的構造函數,也可以添加int參數
-
List testList = new List(10); //長度爲10的list集合 表示List固定長度,不能進行添加 刪除操作 添加數據會提示Exception
-
-
-
創建list
-
//創建一個int類型的list 固定數據類型只能存放固定類型數據 List intList = new List<int>(); //非元素累固定型List 可以存放多種類型格式數據 List listMore = new List(); listMore.add('1'); //String listMore.add(1); //int //長度爲10的list集合 List testList = new List(10);
-
-
常用函數
-
var fruits = new List(); // 添加元素 fruits.add('apples'); // 添加多個元素 fruits.addAll(['oranges', 'bananas']); List subFruits = ['apples', 'oranges', 'banans']; // 添加多個元素 fruits.addAll(subFruits); // 輸出: [apples, oranges, bananas, apples, oranges, banans] print(fruits); // 獲取List的長度 print(fruits.length); // 獲取第一個元素 print(fruits.first); // 獲取元素最後一個元素 print(fruits.last); // 利用索引獲取元素 print(fruits[0]); // 查找某個元素的索引號 print(fruits.indexOf('apples')); // 刪除指定位置的元素,返回刪除的元素 print(fruits.removeAt(0)); // 刪除指定元素,成功返回true,失敗返回false // 如果集合裏面有多個“apples”, 只會刪除集合中第一個改元素 fruits.remove('apples'); // 刪除最後一個元素,返回刪除的元素 fruits.removeLast(); // 刪除指定範圍(索引)元素,含頭不含尾 // fruits.removeRange(start,end); // 刪除指定條件的元素(這裏是元素長度大於6) fruits.removeWhere((item) => item.length > 6); // 刪除所有的元素 fruits.clear(); // 可以使用 sort() 函數來排序, 但是由於我們使用定義的數組類型不一樣,就不能使用 var sortList = [1, 2, 4, 5, 3, 6]; // 根據語法提示: List.sort([(int, int) → int compare]) → void sortList.sort((a, b) => a.compareTo(b)); print(sortList); // 輸出[1, 2, 3, 4, 5, 6] sortList.sort((a, b) => b.compareTo(a)); print(sortList); //[6, 5, 4, 3, 2, 1]
-
Set
-
元素唯一且無序的集合
-
實例
-
var names =new Set<String>(); names.addAll(['dart', 'c#', 'j#', 'e#']);
-
-
創建
-
var names =new Set<String>(); names.addAll(['dart', 'c#', 'j#', 'e#']); Set<String> name = {} as Set<String>; // 這樣也是可以的。 Set<String> n=new Set<String>(); Set ns=new Set(); //Set ns=new Set(2);//不支持指定長度 //var nams = {}; // 這樣會創建一個 Map ,而不是 Set 。
-
-
常用函數
-
使用
add()
或addAll()
爲已有的 Set 添加元素:-
var elements = <String>{}; elements.add('fluorine'); elements.addAll(halogens);
-
-
使用
.length
來獲取 Set 中元素的個數:-
var elements = <String>{}; elements.add('fluorine'); elements.addAll(halogens); assert(elements.length == 5);
-
-
在 Set 字面量前增加
const
,來創建一個編譯時 Set 常量:-
final constantSet = const { 'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine', }; // constantSet.add('helium'); // Uncommenting this causes an error
-
-
Map
-
Map 是用來關聯 keys 和 values 的對象。 keys 和 values 可以是任何類型的對象。在一個 Map 對象中一個 key 只能出現一次。 但是 value 可以出現多次。
-
創建map
-
Map companys = {}; Map company=new Map(); Map ma=Map();// 爲什麼不用new 因爲new 在dart2.0 可選 // 指定鍵值對類型 var aMap = new Map<int, String>(); Map<int,String> aMap = new Map<int, String>();
-
-
數據添加
-
//初始化裏面寫key和value,每組鍵值對中間用逗號隔開。 Map companys = {'Alibaba': '阿里巴巴', 'Tencent': '騰訊', 'baidu': '百度'}; // 通過key-value添加 companys["accenture"]="埃森哲"; // 通過整體合併另一個map 泛型要一致 var fruit = new Map(); fruit["first"] = "apple"; fruit.addAll(companys); //addEntries() 合併兩個map 如果key有重複,被合併的map的value覆蓋前者 // 形勢一 通過Map Map<String,int> map26 = {"a":1,"b":2,"c":3}; Map<String,int> map27 = {"a":1,"b":4,"d":3,"e":5}; map26.addEntries(map27.entries); //print(map26);//{a: 1, b: 4, c: 3, d: 3, e: 5} // 形式二 通過list<MapEntrie> List<MapEntry<String, String>> list = new List(); list.add(MapEntry("keyadd", "valueAdd")); fruit.addEntries(list.reversed); //通過Iterable增加數據
-
-
取出數據 通過key
-
var gifts = {'first': 'partridge'}; assert(gifts['first'] == 'partridge'); //若map中不存在要查找的key map返回null var gifts = {'first': 'partridge'}; assert(gifts['fifth'] == null);
-
-
通過.length函數獲取當前map 的鍵值對個數
-
var m={'key1':'key','key1':'key1}; assert(m.length==2);
-
-
創建map運行時常量 要通過const
-
final constmap=const{'key1':'value1', 'key2':'value2', 'key3':'value3',}; constmap['key1']='hello';//該行代碼會報錯 因爲const 標明的變量值不可修改
-
Rune
謹慎使用 list 方式操作 Rune 。 這種方法很容易引發崩潰, 具體原因取決於特定的語言,字符集和操作。
在 Dart 中, Rune 用來表示字符串中的 UTF-32 編碼字符。
Unicode 定義了一個全球的書寫系統編碼, 系統中使用的所有字母,數字和符號都對應唯一的數值編碼。 由於 Dart 字符串是一系列 UTF-16 編碼單元, 因此要在字符串中表示32位 Unicode 值需要特殊語法支持。
表示 Unicode 編碼的常用方法是,
\uXXXX
, 這裏 XXXX 是一個4位的16進制數。 例如,心形符號 (♥) 是\u2665
。 對於特殊的非 4 個數值的情況, 把編碼值放到大括號中即可。 例如,emoji 的笑臉 是\u{1f600}
。String 類有一些屬性可以獲得 rune 數據。 屬性
codeUnitAt
和codeUnit
返回16位編碼數據。 屬性runes
獲取字符串中的 Rune 。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)); // 輸出 // 👏 // [55357, 56399] // [128079] // ♥ 😅 😎 👻 🖖 👍
Symbol
一個 Symbol 對象表示 Dart 程序中聲明的運算符或者標識符。 你也許永遠都不需要使用 Symbol ,但要按名稱引用標識符的 API 時, Symbol 就非常有用了。 因爲代碼壓縮後會改變標識符的名稱,但不會改變標識符的符號。 通過字面量 Symbol ,也就是標識符前面添加一個
#
號,來獲取標識符的 Symbol 。#radix #bar