天天看點

Flutter(Dart)基礎——資料類型Flutter(Dart)基礎——資料類型小結

Flutter(Dart)基礎——資料類型

Dart 資料類型

Dart 中所有的對象都是對應一個類的執行個體。無論是int、函數和 null 等都是對象。

Dart 中所有對象繼承自 Object 類。

類型推斷

Dart 是代碼類型安全的語言,但是由于其支援類型推斷,是以大多數變量不需要顯式地指定類型。

例如:

var name = 'budaye';
var year = 2020;
var antennaDiameter = 3.7;
var flybyObjects = ['木星', '土星', '天王星', '海王星'];
var image = {
  'tags': ['土星'],
  'url': '//path/to/saturn.jpg'
};
           

dynamic 和 Object

前面我們說過,Dart 裡所有東西都是對象,并且所有對象的父類就是 Object。

使用 Object 時,我們隻是在說接受任意類型,我們需要的是一個 Object。類型系統會保證其類型安全。

如果要明确說明不需要任何類型,需要使用特殊類型 dynamic,dynamic 會告訴編譯器,我們知道自己在做什麼,不用做類型檢測。

當我們調用一個不存在的方法時,會執行 noSuchMethod() 方法,預設情況下(在 Object 裡實作)它會抛出 NoSuchMethodError。為了在運作時檢測進行類型檢測,Dart 提供了一個關鍵字 is。

内置類型

Dart 沒有 byte、char 和 float,并且int、double都是 64 位。

Dart 語言支援下列的類型:

  • numbers
  • strings
  • booleans
  • lists (也被稱為 arrays)
  • sets
  • maps
  • runes (用于在字元串中表示 Unicode 字元)
  • symbols

可以直接使用字面量來初始化上述類型。例如 ‘This is a string’ 是一個字元串字面量,true 是一個布爾字面量。

由于 Dart 中每個變量引用都指向一個對象(一個 類 的執行個體),你通常也可以使用 構造器 來初始化變量。一些内置的類型有它們自己的構造器。例如你可以使用 Map() 來建立一個 map 對象。

Numbers

Dart 支援兩種 Number 類型:

1. int

整數值;長度不超過 64位,具體取值範圍依賴于不同的平台。在 DartVM 上其取值位于 -263 至 263 - 1 之間。編譯成 JavaScript 的 Dart 使用 JavaScript 數字,其允許的取值範圍在 -253 至 253 - 1 之間。

var x = 1;
var hex = 0xDEADBEEF;
           
  1. double

64位的雙精度浮點數字,且符合 IEEE 754 标準。

var y = 1.1;
var exponents = 1.42e5;
           

int 和 double 都是 num 的子類。 num 中定義了一些基本的運算符比如 +、-、*、/ 等,還定義了 abs()、ceil() 和 floor() 等方法(位運算符,比如 » 定義在 int 中)。如果 num 及其子類不滿足你的要求,可以檢視 dart:math 庫中的 API。

從 Dart 2.1 開始,整型字面量将會在必要的時候自動轉換成浮點數字面量:

double z = 1; // Equivalent to double z = 1.0
           

Strings

Dart 裡的 String 跟 Java 中的一樣,是不可變對象;但不同的是,檢測兩個 String 的内容是否一樣,我們使用 == 進行比較;如果要測試兩個對象是否是同一個對象(indentity test),使用 identical 函數。

Dart 字元串是 UTF-16 編碼的字元序列。可以使用單引号或者雙引号來建立字元串:

var s1 = '使用單引号建立字元串字面量。';
var s2 = "雙引号也可以用于建立字元串字面量。";
var s3 = '使用單引号建立字元串時可以使用斜杠來轉義那些與單引号沖突的字元串:\'。';
var s4 = "而在雙引号中則不需要使用轉義與單引号沖突的字元串:'";
           

可以在字元串中以 ${表達式} 的形式使用表達式,如果表達式是一個辨別符,可以省略掉 {}。如果表達式的結果為一個對象,則 Dart 會調用該對象的 toString 方法來擷取一個字元串。

var s = '字元串插值';
assert('Dart 有$s,使用起來非常友善。' == 'Dart 有字元串插值,使用起來非常友善。');
assert('使用${s.substring(3,5)}表達式也非常友善' == '使用插值表達式也非常友善。');
           

注:== 運算符判斷兩個對象的内容是否一樣,如果兩個字元串包含一樣的字元編碼序列,則表示相等。

字元串和數字之間的轉換

// 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');
           

Booleans

Dart 使用 bool 關鍵字表示布爾類型,布爾類型隻有兩個對象 true 和 false,兩者都是編譯時常量。

Dart 的類型安全不允許你使用類似 if (nonbooleanValue) 或者 assert (nonbooleanValue) 這樣的代碼檢查布爾值。相反,你應該總是顯示地檢查布爾值。

Lists

數組 Array 是幾乎所有程式設計語言中最常見的集合類型,在 Dart 中數組由 List 對象表示。通常稱之為 List。

Dart 中 List 字面量看起來與 JavaScript 中數組字面量一樣。下面是一個 Dart List 的示例:

var list = [1, 2, 3];//這裡 Dart 推斷出 list 的類型為 List<int>,如果往該數組中添加一個非 int 類型的對象則會報錯。
           

List 的下标索引從 0 開始,第一個元素的下标為 0,最後一個元素的下标為 list.length - 1。

如果想要建立一個編譯時常量的 List,在 List 字面量前添加 const 關鍵字即可。

擴充操作符(…)和 null-aware 擴充操作符(…?)

Dart 在 2.3 引入了 擴充操作符(…)和 null-aware 擴充操作符(…?),它們提供了一種将多個元素插入集合的簡潔方法。

例如,你可以使用擴充操作符(…)将一個 List 中的所有元素插入到另一個 List 中:

var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);
           

如果擴充操作符右邊可能為 null ,你可以使用 null-aware 擴充操作符(…?)來避免産生異常:

var list;
var list2 = [0, ...?list];
assert(list2.length == 1);
           

Sets

在 Dart 中,set 是一組特定元素的無序集合。 Dart 所支援的 set 由 set literals(Set 字面量) 和 Set 類所提供。 Set 字面量(literals) 是在 Dart2.2 中加入的。

下面是使用 Set 字面量來建立一個 Set 集合的方法:

var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
           

可以使用在 {} 前加上類型參數的方式建立一個空的 Set,或者将 {} 指派給一個 Set 類型的變量:

var names = <String>{}; // 類型+{}的形式建立Set。
// Set<String> names = {}; // 聲明類型變量的形式建立 Set (This works, too).
// var names = {}; // 這樣的形式将建立一個 Map 而不是 Set (Creates a map, not a set.)
           

注意:Map 字面量文法同 Set 字面量文法非常相似。因為先有的 Map 字面量文法,是以 {} 預設是 Map 類型。如果忘記在 {} 上注釋類型或指派到一個未聲明類型的變量上,那麼 Dart 會建立一個類型為 Map<dynamic, dynamic> 的對象。

從 Dart 2.3 開始,Set 可以像 List 一樣支援使用擴充操作符(… 和 …?)以及 Collection If 和 Collection For 操作。

Maps

通常來說, Map 是用來關聯 keys 和 values 的對象。 keys 和 values 可以是任何類型的對象。在一個 Map 對象中一個 key 隻能出現一次。但是 value 可以出現多次。 Dart 中 Map 通過 Map 字面量和 Map 類型來實作。通常來說,Map 是一個鍵值對相關的對象。其中鍵和值都可以是任何類型的對象。每個 鍵 隻能出現一次但是 值 可以重複出現多次。 Dart 中 Map 提供了 Map 字面量以及 Map 類型兩種形式的 Map。

下面是一對使用 Map 字面量建立 Map 的例子:

var gifts = {
  // 鍵:    值
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};

var nobleGases = {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};
           

注意:Dart 将 gifts 變量的類型推斷為 Map<String, String>,而降 nobleGases 的類型推斷為 Map<int, String>。如果你向這兩個 Map 對象中添加不正确的類型值,将導緻運作時異常。

當然,我們也可以使用 Map 的構造器建立 Map對象。

從 Dart 2.3 Map 可以像 List 一樣支援使用擴充操作符(… 和 …?)以及 Collection If 和 Collection For 操作。

小結

本文介紹了Dart的文法基礎:資料類型。

  1. Dart 是代碼類型安全的語言,但是由于其支援類型推斷,是以大多數變量不需要顯式地指定類型。
  2. Dart 中所有的對象都是對應一個類的執行個體。無論是int、函數和 null 等都是對象。
  3. Dart 中所有對象繼承自 Object 類。
  4. Dart 沒有 byte、char 和 float,并且int、double都是 64 位。
  5. 如果要明确說明不需要任何類型,需要使用特殊類型 dynamic,dynamic 會告訴編譯器,我們知道自己在做什麼,不用做類型檢測。

ps:如果覺得本文對你有所幫助,請在文章下方 “點贊” 和 “收藏” 支援下吧~😁

繼續閱讀