dart 01變量、常量、類型

變量

變量聲明

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 and false 是布爾類型, 這兩個對象都是編譯時常量。

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 數據。 屬性 codeUnitAtcodeUnit 返回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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章