Dart基礎(chǔ)(一)-變量、常量、數(shù)據(jù)類型

簡(jiǎn)介:

??Dart是谷歌開(kāi)發(fā)的跨平臺(tái)的計(jì)算機(jī)高級(jí)語(yǔ)言。Dart是面向?qū)ο蟮摹㈩惗x的、單繼承的語(yǔ)言。它的語(yǔ)法類似C語(yǔ)言(更加類似于swift或者kotlin),可以轉(zhuǎn)譯為JavaScript,支持接口(interfaces)、混入(mixins)、抽象類(abstract classes)、泛型(reified generics)、可選類型(optional typing)和靜態(tài)推斷類型sound type system。

Hello world! :

??main()函數(shù)是Dart的入口函數(shù),也是所有Dart語(yǔ)言的開(kāi)端:

void main() {
  print('Hello, World!');
}

Dart中重要的概念:

1.Dart中一切皆對(duì)象:

??在其它面向?qū)ο笳Z(yǔ)言中變量類型一般包含基礎(chǔ)數(shù)據(jù)類型和對(duì)象類型(或者引用類型),例如swift或者java。在Dart中,聲明的每個(gè)變量都是一個(gè)類的對(duì)象;無(wú)論是數(shù)字(numbers),函數(shù)(functions)和null都是對(duì)象;并且除了null(如果你啟用了sound null safety),所有對(duì)象繼承自Object類。

2.Dart中是強(qiáng)引用類型的(strong):

??不像swift或者OC中有weak弱引用,Dart中的變量或者屬性都是strong強(qiáng)引用的。雖然Dart是強(qiáng)類型的,但類型注釋是可選的,因?yàn)镈art可以推斷類型。在下面的代碼中,number被推斷為int類型:

  var number = 23;
  print(number.runtimeType);  // 打印int
3.Dart中是空安全的(null safety):

??null safety是在Dart 2.12中引入的。當(dāng)您選擇null safety時(shí),您代碼中的類型默認(rèn)情況下是不可為空的,這意味著值不能為空,除非您說(shuō)它們可以為空。示例代碼如下:

  int? number2; // number2可以為空也可以是int類型的值
  number2 = null;
  number2 = 34;
  int number3;
  number3 = null; // 報(bào)錯(cuò):number3不能為null
4.Dart中可以推斷確定變量類型:

??Dart中推斷確定變量的類型有兩種,一種是在編譯時(shí),一種是在運(yùn)行時(shí)。在Dart中,聲明變量和屬性基本都是編譯時(shí)已經(jīng)確定其類型,但是用關(guān)鍵字dynamic修飾的變量和屬性是在編譯時(shí)才能確定的。
??dynamic修飾的變量和屬性的值進(jìn)行任何成員訪問(wèn),但可能會(huì)失敗,并在運(yùn)行時(shí)拋出異常。如果您確實(shí)想要那種有風(fēng)險(xiǎn)但靈活的動(dòng)態(tài)分派,那么使用dynamic是合適的類型。
??否則,更喜歡使用Object?Object。在訪問(wèn)值之前,依賴于is檢查和類型提升,以確保值的運(yùn)行時(shí)類型支持希望訪問(wèn)的成員。

            Object? number;   // 可以為任意類型的值
            dynamic number2;  // 可以為任意類型的值
            number = null;
            number = 12;
            number.toString();
            number = '123'; // 上一行number是int值,可以改變變量的類型
            // print(number + 1);  // 編譯時(shí)報(bào)錯(cuò),number2是String值
            if (number is int) {  // 判斷類型
              print(number + 1);
            }
            print(number.runtimeType);
            number2 = null;
            number2 = 12;
            number2 = '123';
            if (number2 is int) {  // 判斷類型
              print(number2 + 1);  // 編譯時(shí)報(bào)錯(cuò)
            }
            print(number2 + 1); // 編譯時(shí)不報(bào)錯(cuò),運(yùn)行時(shí)報(bào)錯(cuò),number2是String值
5.Dart支持泛型類型:

??Dart支持泛型類型,如List<int>(整數(shù)列表)或List<Object>(任何類型的對(duì)象列表)。

6.Dart支持頂級(jí)函數(shù)和變量

??Dart支持頂級(jí)函數(shù)(如main())和變量,以及綁定到類或?qū)ο蟮暮瘮?shù)或者變量(分別為靜態(tài)方法或者靜態(tài)變量和實(shí)例方法或者實(shí)例變量)。還可以在函數(shù)中創(chuàng)建函數(shù)(嵌套函數(shù)或局部函數(shù))。實(shí)例變量有時(shí)被稱為字段或?qū)傩浴?/p>

7.Dart沒(méi)有權(quán)限修飾符:

??與Java不同,Dart沒(méi)有public、protectedprivate權(quán)限修飾符。如果標(biāo)識(shí)符以下劃線(_)開(kāi)頭,則它是其庫(kù)或者類的私有。

8.私有變量、常量、函數(shù)都以下劃線開(kāi)頭:

??標(biāo)識(shí)符可以以字母或下劃線(_)開(kāi)頭,然后是這些字符和數(shù)字的任意組合。

class Some {
  // 靜態(tài)變量,類屬性
  static int type = 0;
  // 實(shí)例變量,實(shí)例屬性,實(shí)例字段
  late final String name;
  // 私有屬性
  late String _privateProperty;
  // 可供外界訪問(wèn)方法
  void show() {
    _show();
  }
  // 靜態(tài)方法,類方法
  static void showType() {
    print(type);
  }
  // 私有函數(shù)
  void _show() {
    print(_privateProperty);
  }
}
9.Dart中的表達(dá)式和語(yǔ)句:

??Dart語(yǔ)法中有expressions( 表達(dá)式有運(yùn)行時(shí)值)和 statements(語(yǔ)句沒(méi)有運(yùn)行時(shí)值 )。 例如,條件表達(dá)式condition ? expr1 : expr2 的值可能是 expr1 或 expr2 。 將其與 if-else 語(yǔ)句相比較,if-else 語(yǔ)句沒(méi)有值。 一條語(yǔ)句通常包含一個(gè)或多個(gè)表達(dá)式,相反表達(dá)式不能直接包含語(yǔ)句。

            var number = 1;
            final bool isBigger;
            if (number > 10) {
              isBigger = true;
            }
            else {
              isBigger = false;
            }
            var isBigger2 = (number > 10) ? true : false;
10.Dart中警告和錯(cuò)誤

??Dart工具可以報(bào)告兩種問(wèn)題:warnings(警告)和errors(錯(cuò)誤)。警告只是表示您的代碼可能無(wú)法工作,但它們不會(huì)阻止您的程序執(zhí)行。錯(cuò)誤可以是編譯時(shí)的,也可以是運(yùn)行時(shí)的。編譯時(shí)錯(cuò)誤會(huì)阻止代碼執(zhí)行;運(yùn)行時(shí)錯(cuò)誤會(huì)導(dǎo)致在執(zhí)行代碼時(shí)引發(fā)異常。

Dart中的關(guān)鍵字

關(guān)鍵字 關(guān)鍵字 關(guān)鍵字 關(guān)鍵字
abstract 2 else import 2 show 1
as 2 enum in static 2
assert export 2 interface 2 super
async 1 extends is switch
await 3 extension 2 late 2 sync 1
break external 2 library 2 this
case factory 2 mixin 2 throw
catch false new true
class final null try
const finally on 1 typedef 2
continue for operator 2 var
covariant 2 Function 2 part 2 void
default get 2 required 2 while
deferred 2 hide 1 rethrow with
do if return yield 3
dynamic 2 implements 2 set 2

??避免使用這些詞作為標(biāo)識(shí)。但是,如果有必要,標(biāo)記有上標(biāo)的關(guān)鍵字可以是標(biāo)識(shí)符。

標(biāo)識(shí)符命名規(guī)則:

  • 變量的名稱必須有數(shù)字,字母,下劃線和美元符($)組成
  • 標(biāo)識(shí)符不能以數(shù)字開(kāi)頭
  • 標(biāo)識(shí)符不能是保留字或關(guān)鍵字,見(jiàn)關(guān)鍵字說(shuō)明
  • 標(biāo)識(shí)符是區(qū)分大小寫的;例如:nameName不是同一個(gè)變量
  • 標(biāo)識(shí)符(變量和函數(shù))一定要通俗名義

變量:

1.變量的定義:

??變量定義有三種常見(jiàn)的方法,一種是var定義,一種是指定具體類型的定義,還有一種是dynamic定義。
??在空安全模式下(null safety),變量在使用之前必須被初始化賦值,除非該變量允許為空(例如int?)。

1.1var定義變量:

??var定義變量,不明確變量的類型,Dart自己會(huì)有類型檢查,會(huì)根據(jù)var關(guān)鍵字在定義變量時(shí)所賦予的初值的類型明確變量的類型。var定義變量根據(jù)賦值的時(shí)機(jī)分為兩種情況:一種是定義時(shí)隨即賦值;一種是先聲明變量,在之后代碼中另行賦值。

1.1.1var定義變量隨即賦值:

??上述中說(shuō)到,在賦值時(shí)確定了變量類型,在賦值之后,可以賦值其它類型嗎?代碼如下:

  var number2 = 12; // 等價(jià)于 int number2 = 12;
  number2 = 14;
  var result = number2 + 1;  // 正常運(yùn)行
  // number2 = null;  // 編譯報(bào)錯(cuò)
  // number2 = '123'; // 編譯報(bào)錯(cuò)

??如代碼所示,這種聲明變量并賦值的變量,其后無(wú)法進(jìn)行其它類型的賦值,它與指定具體類型定義變量等價(jià)。

1.1.2var定義變量后,另行賦值:

??與1.1.1中問(wèn)題進(jìn)行對(duì)比:

  var number; // 等價(jià)于 Object? number;
  number = 12;
  number = null;  // 不會(huì)報(bào)錯(cuò)
  number = '123'; // 不會(huì)報(bào)錯(cuò)
  // var result = number + 1;  // 編譯時(shí)通過(guò),運(yùn)行時(shí)報(bào)錯(cuò),上一行代碼表示,number為String類型
  var result2 = number + '1';  // 正常運(yùn)行

??如代碼所示,這種聲明并賦值的變量,其后可以進(jìn)行其它類型的賦值,并且該變量的類型與最近一次賦值的類型相同;但是之后對(duì)其進(jìn)行已賦值過(guò)的類型進(jìn)行操作,編譯時(shí)不會(huì)報(bào)錯(cuò),運(yùn)行時(shí)會(huì)報(bào)類型不匹配的錯(cuò)誤;該定義變量與指定類型為Object?變量等價(jià)。

1.2指定具體類型的定義變量:
  int number = 1;
  String str = '123';
1.3動(dòng)態(tài)變量即dynamic定義的變量:

??dynamic定義的變量,編譯時(shí)不會(huì)進(jìn)行其類型的確定,而是在運(yùn)行時(shí)確定;并且該變量可以進(jìn)行任意類型的操作,編譯時(shí)不報(bào)錯(cuò),只有在運(yùn)行時(shí)才會(huì)報(bào)錯(cuò);其運(yùn)行時(shí)的類型與最近一次賦值的類型相同。

  dynamic number = 1;
  var result = number + '1';  // 編譯通過(guò),運(yùn)行時(shí)報(bào)類型不匹配錯(cuò)誤
  number = '123';
  var result2 = number + '4';  // 正常運(yùn)行

??dynamic一般用于泛型(以后會(huì)講到),且必須對(duì)其類型有確切的掌握,不然運(yùn)行時(shí)報(bào)錯(cuò)就不可避免了。

2.初始值(Default value):
  • 具有可空類型的未初始化變量的初始值為null,
  • 在空安全模式下(null safety),局部變量在使用之前必須被初始化賦值,除非該變量允許為空(例如int?)。
  • 頂級(jí)和類變量是延遲初始化的,且使用之前必須被初始化賦值。
  int? number2;
  print(number2);
  int number;
  // print(number);  // 空安全模式下,number沒(méi)有初始化,且不能為空,所以報(bào)錯(cuò)
  number = 2;
  print(number); // 正常運(yùn)行
class Some {
  // static int type; // 報(bào)錯(cuò)
  static int type = 1;
}

常量:

定義:

??不更改的變量或者初始化后無(wú)法更改的變量就是常量,在Dart中聲明常量用關(guān)鍵字const或者final。

constfinal聯(lián)系:
  • 都是編譯時(shí)常量;
  • 只能初始化賦值一次,其后無(wú)法修改值;
  • 在類中都可以和static一起使用表示類級(jí)別的屬性。
constfinal區(qū)別:
  • const常量聲明時(shí)可以省略,而final不能省略;
  • 類中聲明屬性和字段使用final,不用const
  • const常量為編譯時(shí)常量,聲明時(shí)必須初始化賦值,而final常量還是運(yùn)行時(shí)常量可以先聲明再賦值(即常說(shuō)的懶加載),但是final常量必須在使用前進(jìn)行初始化賦值;
  • const修飾對(duì)象時(shí),對(duì)象的屬性無(wú)法修改,而final修飾對(duì)象,對(duì)象屬性可以修改。

內(nèi)置類型:

Dart支持的類型:
  • Numbers (數(shù)值類型int, double)
  • Strings (字符串String)
  • Booleans (bool)
  • Lists (List,常見(jiàn)的數(shù)組)
  • Sets (集合Set)
  • Maps (哈希表或者字典Map)
  • Runes (Runes;通常被“characters”API所取代)
  • Symbols (符號(hào)Symbol)
  • 空值 null (空類Null)
Dart特殊的類型:
  • Object:除Null外的所有Dart類的超類;
  • FutureStream:用于異步支持;
  • Iterable:用于for-in循環(huán)和同步生成器函數(shù);
  • Never:表示一個(gè)表達(dá)式永遠(yuǎn)不能成功完成求值,通常用于總是拋出異常的函數(shù);
  • dynamic:表示要禁用靜態(tài)檢查,通常你應(yīng)該使用Object?代替;
  • void:表示該值從未被使用。通常用作返回類型。
Numbers類型:

??整形數(shù)值類型(int);其取值范圍,不大于64位的整數(shù)值,取決于平臺(tái);在本地平臺(tái)上,值可以從-263到263 - 1。在web上,整數(shù)值表示為JavaScript數(shù)字(64位浮點(diǎn)值,沒(méi)有小數(shù)部分),取值范圍從-253到253 - 1。
??double類型:64位(雙精度)浮點(diǎn)數(shù),由IEEE 754標(biāo)準(zhǔn)指定。
??intdouble都是 num的子類。num類型包括基本操作符,如+、-、/和*,在這里您還可以找到abs()、ceil()floor()等方法。(位操作符,如>>,定義在int類中。)如果num及其子類型沒(méi)有您要尋找的內(nèi)容,那么dart:math庫(kù)可能有。

            var x = 1;
            var hex = 0xDEADBEEF;
            var exponent = 8e5;
            var y = 1.1;
            var exponents = 1.42e5;
            num n = 1; // x可以是int或者double
            n += 2.5;
            assert((3 << 1) == 6); // 0011 << 1 == 0110
            assert((3 | 4) == 7); // 0011 | 0100 == 0111
            assert((3 & 4) == 0); // 0011 & 0100 == 0000
Strings類型:
  • String類型包含一個(gè)UTF-16代碼單元序列;
  • 可以用''或者""初始化賦值;
  • 可以用r初始化賦值;
  • 可以用‘’‘’‘’或者""""""初始化多行字符串;
  • 可以用+拼接字符串;
  • 可以用==判斷字符串內(nèi)容相同。
            String s1 = '123';
            String s2 = "123";
            String s3 = r"123";
            String s4 = '''123
            456
            789
            ''';
            String s5 = """123
            456
            789
            """;
            var s6 = "I am " + "Lucy!";
            print("object" == "object");  // true
Booleans類型:
  • bool類型,兩個(gè)值truefalse;它們都是編譯時(shí)常量;
  • 條件判斷沒(méi)有隱式類型轉(zhuǎn)換。
            var number = 123;
            var str = '123';
            if (number == str) {
              print("隱式轉(zhuǎn)換");
            }
            else {
              print("沒(méi)有轉(zhuǎn)換");  // 沒(méi)有轉(zhuǎn)換
            }
Lists類型:
  • List中元素可以重復(fù);
  • 支持if,for,...,...?等語(yǔ)法;
    ??List數(shù)組類型,常見(jiàn)初始化和操作代碼如下:
            var intList = [1, 2, 3];
            List<int> intList3 = <int>[];
            var list2 = [0, ...intList];
            var strList = ['Car', 'Boat','Plane',];
            List<String> strList2 = <String>[];
            var hasZheng = true;
            var strList3 = [
              '周',
              '吳',
              if (hasZheng) '鄭',
            ];
            var listOfInts = [1, 2, 3];
            var listOfStrings = [
              '#0',
              for (var i in listOfInts) '#$i'
            ];
            print(listOfStrings);
Sets類型:
  • Set中元素唯一;
  • 支持iffor,......?等語(yǔ)法;
    ??Set集合類型,常見(jiàn)初始化和操作代碼如下:
            var intSets = {1, 1, 1};
            var intSets2 = <int>{};
            intSets2.add(2);
            intSets2.addAll(intSets);
            print(intSets); // {1}
            print(intSets2);  // {2, 1}
            var hasZheng = true;
            Set<String> strSets = {'周', '吳', if (hasZheng) '鄭'};
            Set<String> strSets2 = {...strSets, '王'};
            print(strSets2);  // {周, 吳, 鄭, 王}
Maps類型:
  • Map是一個(gè)關(guān)聯(lián)鍵(key)和值(value)的對(duì)象的集合;
  • 鍵和值都可以是任何類型的對(duì)象;
  • 每個(gè)鍵只出現(xiàn)一次,但您可以多次使用相同的值;
  • 支持iffor,...,...?等語(yǔ)法;
    ??Set集合類型,常見(jiàn)初始化和操作代碼如下:
            var nameMap = {"first" : "周", "second" : "吳"};
            nameMap['third'] = "鄭";
            Map<int, String> someMap = {1 : "周", 2 : "吳"};
            var someMap2 = {1 : "周", 2 : "吳", ...someMap};
            print(nameMap); // {first: 周, second: 吳, third: 鄭}
            print(someMap2);  // {1: 周, 2: 吳}

其它:

Dart之旅

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容