第一節(jié): Dart語法了解,認識變量,常量,數(shù)據(jù)類型

Dart 語法學(xué)習(xí)目錄

第一節(jié): Dart 語法了解,認識變量,常量,數(shù)據(jù)類型
第二節(jié): Dart 操作符(運算符)
第三節(jié): Dart 中常用集合 List/Map
第四節(jié): Dart 函數(shù)使用,聲明函數(shù)/匿名函數(shù)/可選參數(shù)/作用域/閉包
第五節(jié): Dart 面向?qū)ο?構(gòu)造函數(shù)/靜態(tài)屬性
第六節(jié): Dart中抽象類abstract/接口implements/混入Mixin
第七節(jié): Dart中泛型/泛型定義與使用
第八節(jié): Dart 中的庫/自定義庫/內(nèi)置庫/第三方庫

1. dart的基本用法了解

1.1 dart入口函數(shù)與輸出

dart運行需要一個入口函數(shù)為main,

通過下面的示例,先簡單了解dart基本使用

在dart語法中輸出控制臺為print() 方法

// 有返回值的dart
main(){
    // 打印
    print("hello dart")
}

結(jié)果會在控制臺輸出hello dart

我們也可以將main 入口函數(shù)定義為沒有返回值的函數(shù),

// 沒有返回指定入口
void main(){
    print("你好 dart")
}

void 是限定函數(shù)的返回來寫為空

1.2 dart語言中的注釋
//   單行注釋
///  單行注釋
/* 
    多行注釋 
*/

2. Dart 語言重要概念的理解

  1. 任何保存在變量中的都是一個 對象 , 并且所有的對象都是對應(yīng)一個 的實例。 無論是數(shù)字,函數(shù)和 null 都是對象。所有對象繼承自 Object類。
  2. 盡管 Dart 是強類型的,但是 Dart 可以推斷類型,所以類型注釋是可選的。
  3. Dart 支持泛型,如 List <int> (整數(shù)列表)或 List <dynamic> (任何類型的對象列表)
  4. Dart 支持頂級函數(shù)(例如 main() ), 同樣函數(shù)綁定在類或?qū)ο笊希ǚ謩e是 靜態(tài)函數(shù)實例函數(shù) )。 以及支持函數(shù)內(nèi)創(chuàng)建函數(shù) ( 嵌套局部函數(shù) ) 。
  5. Dart 支持頂級 變量 , 同樣變量綁定在類或?qū)ο笊希o態(tài)變量和實例變量)。 實例變量有時稱為字段或?qū)傩浴?/li>
  6. 與 Java 不同,Dart 沒有關(guān)鍵字 “public” , “protected” 和 “private” 。 如果標識符以下劃線(_)開頭,則它相對于庫是私有的。
  7. 標識符 以字母或下劃線(_)開頭,后跟任意字母和數(shù)字組合。
  8. Dart 語法中包含 表達式( expressions )(有運行時值)和 語句( statements )(沒有運行時值)。 例如,條件表達式condition ? expr1 : expr2 的值可能是 expr1expr2 。 將其與 if-else 語句相比較,if-else 語句沒有值。 一條語句通常包含一個或多個表達式,相反表達式不能直接包含語句。
  9. Dart 工具提示兩種類型問題:警告錯誤。 警告只是表明代碼可能無法正常工作,但不會阻止程序的執(zhí)行。 錯誤可能是編譯時錯誤或者運行時錯誤。 編譯時錯誤會阻止代碼的執(zhí)行; 運行時錯誤會導(dǎo)致代碼在執(zhí)行過程中引發(fā) [異常]

這些重要的概念先有第一定的了解,讀一讀, 不理解什么意思沒有關(guān)系,繼續(xù)往后學(xué),等學(xué)完dart以后在會來來理解這些概念

3. Dart語言中的關(guān)鍵字

關(guān)鍵字先看一眼,混個眼熟, 不用刻意的去背,隨著學(xué)習(xí)的深入,大部分關(guān)鍵詞都會接觸到,或者在自己的代碼示例中出現(xiàn),用多了就熟了

關(guān)鍵字就不在這里羅列了, 了解請移步官網(wǎng)關(guān)鍵字

4. dart中的變量

4.1 dart 標識符命名規(guī)則
  1. 變量的名稱必須有數(shù)字,字母,下劃線和美元符($)組成
  2. 標識符不能以數(shù)字開頭
  3. 標識符不能是保留字或關(guān)鍵字
  4. 變量的名稱是區(qū)分大小寫的, 如果,age和 Age不是同一個變量
  5. 標識符(變量)一定要見名知意,
4.2 變量定義
  1. 使用var 聲明變量,此時沒有明確類型,編譯的時候根據(jù)值明確類型

  2. dart變量定義時可以明確類型,來幫助 Dart 去捕獲異常以及 讓代碼運行的更高效

  3. 變量定義為初始化賦值,變量默認值為null

  4. 如果對象不限于單一類型(沒有明確的類型),請使用Object或dynamic關(guān)鍵字

根據(jù)上面變量定義的描述,我們來好好通過示例來看看變量定義的描述

4.2.1 不明確類型的定義變量

是有var定義變量,不明確變量的類型,dart自己會有類型檢查, 會根據(jù)var關(guān)鍵字在定義變量時所賦予的初值的類型明確變量的類型

void main(){
    // 定義變量
    // var 定義變量, 值是什么類型,變量就是什么類型
    var str = "hello wrod";
    var num = 1234;

    // 打印變量
    print(str);
    print(num);

    // 判斷str num 變量的類型
    print(str is String); // true
    print(num is int);   // true

}

通過示例的打印結(jié)果,我們知道了strnum兩個變量的數(shù)據(jù)類型

所以var 定義變量的類型是根據(jù)第一次賦值變量的時候推到出來的類型, 也就是說在賦予初始值的時候,變量的類型就已經(jīng)確定了,

那么問題來了,類型確定了之后的變量還能賦予其他類型的值嗎?

看示例:

void main(){
    var str2 = '';
    strs = 123;
    print(str2);
}

// 這樣寫就會報錯, str2 是字符串類型, 賦值數(shù)字報錯

我們發(fā)現(xiàn)一旦變量類型確定在賦值其他類型的變量就會報錯.

但是如果通過var 定義變量 并沒有賦初值, 那么這個變量不就沒辦法確定類型

那么此時的類型應(yīng)該還是默認的類型Null,這樣的話,我們是否可以自由給變量賦予任何數(shù)據(jù)類型的值呢

所有后面可以自由賦值任何數(shù)據(jù)類型的值,并且可以更改, 當然不建議這么使用

void main(){
    var num;
    // var 定義變量沒有賦予初始值, 類型為Null
    print(num is Null); // true

    num = 123; 
    print(num);     // 123

    // 當重新給變量賦值時,類型也會發(fā)生變化
    print(num is int);   // true
    print(num is Null);  // false 

    num = "str";
    print(num);    // 'str'

    // 還可以自由賦予不同數(shù)據(jù)類型的值
    print(num is String);  // true
    print(num is Null);  // false
}

示例中的代碼不會報錯, 可以正常輸出結(jié)果.這樣我們就了解了

Dart中,如果使用var關(guān)鍵詞定義變量但是沒有賦予初始,就好像dart沒法限定變量為某一種類型,此時就會像JavaScript變量一樣, 可以賦予任何數(shù)據(jù)類型的值, 而此時變量的類型將有賦予的值的類型來決定

注意:

使用var定義變量但未賦予初始值. 那么變量的值為null,類型為Null

void main(){
    var num;  
    print(num == null);  // true
    print(num is Null);  // true
}

總結(jié):

4.2.2 通過指定類型定義變量

當然了dart也可以在定義變量時限定變量的類型,變量的類型一但被限定, 將不能給變量賦予不同類型的值

示例:

void main(){
  // 定義變量
  // 確定str的類型是字符串類型的變量, str只能賦值字符串,如果賦值其他類型值將會報錯
  String str = "hello wrod";

  // 限定變量num是數(shù)字類型
  int num = 1234;

  // 打印變量
  print(str);
  print(num);
}

注意, var 定義變量時,var 后面就不要在寫類型了, 限定了變量類型就不要在使用var了

現(xiàn)在我們對于數(shù)據(jù)類型還不是特別了解,先認識一下示例中所有的數(shù)據(jù)類型,后面會詳細探討.

4.3 動態(tài)類型dynamic

沒有指定類型的變量的類型為 dynamic,

void main(){
    dynamic num = 123;
    print(num);

    num = '456';
    print(num);

    print(num is dynamic);    // true
    print(num is String);     // true
}

此時并未指定num變量的類型,類型是有值推導(dǎo)出來的, 所以我們在判斷num類型的時候,dynamicString都為true

dynamic 一般在使用泛型時使用

示例:

void main(){
    var list = new List<dynamic>();  //泛型,會在后面總結(jié)
    list.add("hello");
    list.add(123);
    print(list);  // [hello, 123]
}

此時表示集合list里可以放任意數(shù)據(jù)類型的值

泛型是什么?先不用在意,我們會進行總結(jié)

5. Dart 中定義常量

5.1 常量定義的基本用法

dart中使用final 和const 關(guān)鍵字定義常量

對于Dart定義常量的了解

  1. finalconst 修飾的變量只能賦值一次,不可更改變量值(定義常量)
  2. 一個 final 變量只能被初始化一次; const變量是一個編譯時常量,(Const變量是隱式的final),如果 const 常量在類中,請定義為 static const。
  3. 被final或者const修飾的變量,變量類型可以省略,建議指定數(shù)據(jù)類型。
  4. 使用關(guān)鍵字定義常量時必須在第一次聲明的時候就需要初始化,否則會提示錯誤:
5.1.1 定義常量

常量就是定義之后,不能再修改值的變量.

void main(){
    // 定義常量
    // const 定義常量
    const str = "不可修改的值";
    print(str);   // 不可修改的值

    // final 定義常量
    final num = 123;
    print(num); //123

}

示例中,可以正常打印出數(shù)值, 但是這些常量已經(jīng)固定, 如果改變這些常量的值,就會報錯

如下錯誤的寫法

void main(){
  // 定義常量
  const str = "不可修改的值";

  print(str);

  str = '錯誤的';  // 會報錯,常量不可修改
  print(str);

}

通過示例,我們發(fā)現(xiàn)常量就算你修改為一樣類型的數(shù)值也會報錯

5.1.2 指定常量類

finalconst 定義常量,其實就是定義變量,這兩個關(guān)鍵字在修飾變量是,不允許變量被重新賦值而已, 這兩個關(guān)鍵字在修飾常量時,可以省略數(shù)據(jù)類型,

如果在finalconst修飾常量時沒有指定類型,那么變量的類型將有初始賦值的類型決定.

示例:

定義常量時不限定類型

void main(){
    // 定義常量
    // const 定義常量
    const str = "不可修改的值";
    print(str);          // 不可修改的值
    print(str is String);  // true

    // final 定義常量
    final  num = 123;
    print(num);         //123
    print(num is int);   // true

}

通過示例,發(fā)現(xiàn)定義的常量類型就是賦值的數(shù)據(jù)類型

定義變量時限定類型

void main(){
    // 定義常量 限定類型
    // 在修飾常量的關(guān)鍵字和變量之前添加修飾變量的類型

    // const 定義常量
    const String str = "不可修改的值";
    print(str);          // 不可修改的值
    print(str is String);  // true

    // final 定義常量
    final int num = 123;
    print(num);         //123
    print(num is int);   // true

}

我們發(fā)現(xiàn)提前修飾變量的類型也沒有任何問題

如果你修改時的變量類型和賦值的類型不一致就會報錯

void main(){
    // 定義常量 限定類型
    // 在修飾變量的類型和賦值的類型不一致

    // const 定義常量
    const int str = "不可修改的值";
    print(str);          
    print(str is String); 

}

此時不會打印任何內(nèi)容,會直接報錯,因為修飾str變量的類型是int,可是賦予的值的類型是String,所以會直接報錯

5.1.3 聲明常量初始化賦值,

聲明常量時必須在初始化賦值, 否則就會報錯

void main(){
    // 定義常量 聲明時必須初始化賦值

    // const 定義常量
    //   const str ;
    //   str = "不可修改的值"

    final num;
    num = 20;
}

無論final還是const在聲明時未初始化賦值都會報錯;

5.2 const 和final 定義常量的區(qū)別
5.2.1 常量固定下來的時間不同

Const 變量在編譯時就已經(jīng)固定,最高級 final 變量或類變量在第一次使用時被初始化。

final不僅有const 的編譯時常量的特性,最重要的是他運行時常量, final是惰性初始化, 即在運行時第一次使用前才初始化;

void main(){
    // 因為 const 聲明常量時 在定義時就初始化,所以這么寫是錯誤的
    // 所以在const 聲明變量在編譯時就已經(jīng)固定了,所以此時賦予的是不能是表達式,而應(yīng)該是一個確定的值. 
    // 所以如下寫法是會報錯了\

    //   寫法一: 實例化
    //   const aa = new DateTime.now();  

    //   寫法二:計算
    //   var num = 10;
    //   const aa = 123 * num;

    //   print(aa);

    // final 是在第一次使用前才初始化
    // 所以在聲明常量賦值是并沒有固定下來,因此初始賦值可以為表達式
    // 下面兩種寫法完全沒問題

    //   寫法一: 實例化
    //   final aa = new DateTime.now();

    //   寫法二: 計算
    var num = 10;
    final aa = 123 * num;

    print(aa);

}

5.2.2 修飾類的實例

注意修飾類實例的變量可以是final類型 ,但不能是const類型

class Person{
    // 類屬性
    String name = '你好';

    // 類方法
    getInfo(){
        print(name);
    }
}

void main(){
    // 類實例化
    // final 修飾類實例化變量
    final person = new Person();
    person.getInfo();   // 你好

    // const就是就會報錯
    // const person = new Person();   // 報錯
}

因為const是在聲明時固定的,所以不能用來修飾類實例化的常量

5.2.3 修飾變量值

任何一個變量都可以擁有一個常量的值

const關(guān)鍵字不只是聲明常數(shù)變量,您也可以使用它來創(chuàng)建常量值,以及聲明創(chuàng)建常量值的構(gòu)造函數(shù),任何變量都可以有一個常量值。

例如:

void main(){
  var foo = [1,2,3];
  foo.add(6);
  print(foo);  // [1, 2, 3, 6]
}

這樣改變值 沒有任何關(guān)系

但是如果把值限定為常量就會報錯

void main(){
    var foo = const [1,2,3];
    foo.add(6);
    print(foo);  // Cannot add to an unmodifiable list
}

因為此時被const修飾的集合[1,2,3]是常量值,不能修改.

但是要注意的是盡管你是用了const限定了常量值,讓集合不能添加內(nèi)容,但是foo確實變量,所以可以直接替換為非常量值

void main(){
    var foo = const [1,2,3];

    // 將變量修改為非const值
    foo = [4,5,6];
    // 此時就可以修改二兩
    foo.add(7);
    print(foo);  // [4, 5, 6, 7]

}

final關(guān)鍵值不能修飾常量值,

如果使用final修飾常量值就會報錯

void main(){
    var foo = final [1,2,3];  // 直接過錯
}

6. dart的數(shù)據(jù)類型

6.1 類型的了解

常用的數(shù)據(jù)類型

  1. Numbers( 數(shù)值)

    int

    double

  2. Strings (字符串)

    String

  3. Booleans (布爾)

    bool

  4. List (集合,也被稱為數(shù)組)

    在Dart中,數(shù)組是列表對象, 所以大多數(shù)人只是稱他們?yōu)榱斜?/p>

  5. Map(字典)

    通常來說 Map 是一個鍵值對相對的對象, 鍵和值可以是任何類型的對象,每個鍵

不常用的類型

  1. Set
  2. Rune
  3. Symbol

不常用的方法在這里就不羅列了, 之后有用到咱們在說.

這些類型都可以被初始化為字面量,因為在 Dart 所有的變量終究是一個對象(一個類的實例), 所以變量可以使用 構(gòu)造涵數(shù) 進行初始化。一些內(nèi)建類型擁有自己的構(gòu)造函數(shù)。

實例:

void main(){
    String str = "字符串";
    print(str);  // 字符串
}

6.2 數(shù)值類型

Dart 語言的 Number 有兩種類型:

一種是int ,一種是double

  1. int:其取值通常位于 -253和 253-1 之間
  2. double:64-bit (雙精度) 浮點數(shù),符合 IEEE 754 標準。

intdouble 都是 num的亞類型。

void main(){

  // 定義數(shù)值類型
  //  整數(shù)類型不包含小數(shù)點
  int num1 = 23;  // init 只能是整型,如果賦值浮點型就報錯

  double num2 = 22.5; // double可以是整型也可以是浮點型
  num2 = 21;

  print(num1);
  print(num2);
}

6.3 字符串類型

字符串的創(chuàng)建

  1. 使用單引號'',雙引號""
  2. 使用三個 引號'''或雙引號""" 創(chuàng)建多行字符串
  3. 使用r 創(chuàng)建原始 raw 字符串
6.3.1 定義單行字符串
void main(){

  // 單行字符串
  var str1 = '這是單行字符串';
  var str2 = "這是單行字符串";

  String str3 = '這是單行字符串';
  String str4 = "這是單行字符串";

  print(str1);
  print(str2);
  print(str3);
  print(str4);
}

6.3.2 定義多行字符串

定義多行字符串的字面量是三個單引號或三個雙引號

語法

var str = ''' ''';

var str = """ """;

void main(){

  // 單行字符串
  var str1 = '''
    這是多行字符串
    這是多行字符串
  ''';
  var str2 = """
    這是多行字符串
    這是多行字符串
  """;

  String str3 = '''
    這是多行字符串
    這是多行字符串
  ''';
  String str4 = """
    這是多行字符串
    這是多行字符串
  """;

  print(str1);
  print(str2);
  print(str3);
  print(str4);
}

6.3.3 使用r創(chuàng)建字符串
void main(){
    String str = r"Hello World";
    print(str);  // Hello World
}

了解即可

6.3.4 字符串的拼接
void main(){

    String str1 = '你好';
    String str2 = "dart";
    // 1\. 使用加好拼接字符串
    print(str1 + ' ' + str2 );  // 你好 dart

    // 2\. 使用$ 拼接字符串
    print("$str1 $str2");    // 你好 dart

    // 3\. 如果需要運算可以使用${}語法
    int num = 20;
    int num2 = 30;

    print("運算結(jié)果:${num + num2}"); // 運算結(jié)果:50
}

6.3.5 字符串和數(shù)字相互轉(zhuǎn)換的方
void main(){
    // 字符串轉(zhuǎn)為數(shù)字類型
    var one = int.parse("123");
    print(one);  // 123
    var point = double.parse("123.11");
    print(point);  // 123.11

    // 數(shù)字類型轉(zhuǎn)字符串類型
    var str = 123.toString();
    print(str);    // 123
    var strpoint = 123.111.toString();
    print(strpoint);  // 123.111

    // double轉(zhuǎn)字符串先得小數(shù)位數(shù)
    var strpoint2 = 123.161.toStringAsFixed(2);
    print(strpoint2); // 123.11
}

6.4 布爾類型

在dart中定義布爾類型的關(guān)鍵字是bool

布爾值只有個truefalse,它們都是編譯時常量。

void main(){

  // 定義布爾類型
  bool flag1 = true;

  bool flag2 = false;

  print(flag1);
  print(flag2);
}

添加判斷判斷

void main(){

  // 定義布爾值
  bool flag = true;

   // 條件判斷
  if(flag){
    print("真");
  }else{
    print("假");
  }

}

要注意dart條件判斷沒有隱式類型轉(zhuǎn)換

void main(){

  var num = 123;
  var num2 = '123';

  if(num == num2){
    print("num和num2的類型和值都相等");
  }else{
    print("num和num2的類型或者值不相等");
  }

}

// 答應(yīng)不相等, == 不會進行類型轉(zhuǎn)換

6.5 集合類型 (List)

集合就像我們js里面的數(shù)組,只是叫法不一樣

定義集合

字面量定義集合

void main(){

  // 定義集合
  // 1\. 字面量的方式定義集合
  var list = ["張三","李四",'王五', 123];

  // 打印集合
  print(list);

  // 打印集合長度
  print(list.length);

  // 打印集合中的某一個值
  print(list[1]);

}

通過List 構(gòu)造函數(shù)創(chuàng)建集合

void main(){

  // 定義集合

  // 2\.  通過List 構(gòu)造函數(shù)創(chuàng)建集合
  List list = new List();

  // 給集合添加內(nèi)容
  list.add("張三");

  list.add(123);

  list.add(true);

  print(list);

}

指定集合內(nèi)容的類型

void main(){

  // 定義集合
  // 3\. 指定集合內(nèi)容類型
  List list = new List<String>();
  // <String> 指定集合list里每一項只能為字符串類型

  list.add("張三");

  // 給list添加了一個不是字符串類型的值會報錯
  list.add(123);

  print(list);

}

6.6 Maps類型

Map 通常也被稱之為 字典或者 hash ,也是一個無序的集合,里面 包含一個 key-value 對。map 把 key 和 value 關(guān)聯(lián)起來可以 方便獲取數(shù)據(jù)。

有點類似于JS中的JSON對象, JS中的普通對象,屬性可以不用加引號, dart中Maps類型屬性一定要加引號(單引雙引都可以)

所以注意, JavaScript 對象Object 不是 Maps。

void main(){

  // 定義Maps類型;
  // 1\. 字面量定義map
  var map = {
    "name":"wuwei",
    'age': 18,
    "work": ["程序員", "外賣員"]
  };

  print(map);

  // map操作
  // map的操作不能使用點語法,只能使用中括號語法
  // 中括號語法單引雙引都可以 
  print(map['name']);
  print(map["age"]);

}

除了字面量定壓力Map外,還可以采用構(gòu)造函數(shù)定義Map

void main(){

  // 定義Maps類型;

  // 2\. 構(gòu)造函數(shù)定義Map
  Map map = new Map();

  map['name'] = 'wuwei';
  map["work"] = ["程序員", "外賣員"];

  print(map);
}

注意點:

  1. 鍵和值都可以是任何類型的對象。
  2. 每個 鍵 只出現(xiàn)一次, 而一個值則可以出現(xiàn)多次

7. 判斷數(shù)據(jù)類型

在dart中可以使用is關(guān)鍵字來判斷數(shù)據(jù)類型

void main(){

  // 判斷數(shù)據(jù)類型
  // 通過 is關(guān)鍵字
  // var str = '123';
  var str = 123;

  if(str is String){
    print("String 類型");
  }else if(str is int){
    print("int 類型");
  }else{
    print("其他 類型");
  }
}

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

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

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