Flutter入門(三)Dart基礎(chǔ)語法

從上兩篇文章中我們對Flutter已經(jīng)有一個大概的了解,接下來我們從Dart 語法來進一步了解Flutter,我們從以下幾個部分來入手:

  • 1.Dart中的變量與常量
  • 2.Dart中的數(shù)據(jù)類型
  • 3.Dart中的運算符
  • 4.Dart中的方法

1.Dart中的變量常量

1.1 var變量

//變量聲明初始化
void varibleFunc() {
  var name;
  print(name);
  name = 'MG';
  print(name);
  name = 1;
  print(name);

  var age = 18;
  print(age);
}

打印結(jié)果

flutter: null
flutter: MG
flutter: 1
flutter: 18

說明:

  • 使用var聲明一個變量,可以賦值不同的類型
  • var聲明的變量如果沒有初始化,那么它的值為nil

1.2final 最終變量

//最終變量聲明初始化
void finalVariableFunc() {
  final name;
  print(name);
  name = 'MG';
  print(name);
  name = 'xm';
  print(name);
}

此時編譯器會報錯

  • 使用final聲明的一個只能賦值一次的變量
  • 使用final聲明的變量在使用之前必須賦值
  • 它是最終變量

1.3const常量

//常量聲明初始化
void constanFunc() {
  const name = 'LH';
  print(name);
  //這里再次賦值,編譯器會報錯
  //name = "MG";
  //print(name);
}
  • 使用const聲明的常量在聲明時就得賦值
  • 使用const聲明的常量賦值后不能修改

如果您從未打算更改變量,可以使用 finalconst 來代替 var 或添加到類型之外。final變量只能設(shè)置一次; const變量 是編譯時常量。(Const變量 隱式為final。)最終的頂級變量或類變量在第一次使用時進行初始化。

2.Dart中的數(shù)據(jù)類型

Dart 語言對以下類型有特殊的支持:

  • numbers
  • strings
  • booleans
  • lists
  • sets
  • maps
  • runes
  • symbols

可以使用字面量 初始化這些特殊類型中的任何一個對象。例如,this is a string 是一個字符串字面量,而 true 是一個布爾字面量。

因為 Dart 中的每個變量都指向一個對象(類的實例),所以通??梢允褂脴?gòu)造函數(shù)來初始化變量。一些內(nèi)置類型有自己的構(gòu)造函數(shù)。例如,您可以使用 Map() 構(gòu)造函數(shù)來創(chuàng)建映射

2.1num類型

Dartnum有兩種,intdouble

//num類型
void numFunc() {
  num i = 2;
  print(i);
  i = 1.1;  //用num聲明的變量這里是可以轉(zhuǎn)換類型的
  print(i);

  int a = 1;
  print(a.isEven);  //是否偶數(shù)
  print(a.isOdd);   //是否奇數(shù)

  double b = 1.12;
  print(b);

  // String -> int
  int one = int.parse('1');
  print(one + 2);  // 輸出3

  // String -> double
  var onePointOne = double.parse('1.1');
  print(onePointOne + 2);  // 輸出3.1

  // int -> String
  String oneAsString = 1.toString();
  // The argument type 'int' can't be assigned to the parameter type 'String'
  //print(oneAsString + 2);
  // 輸出 1 + 2
  print('$oneAsString + 2');
  // 輸出 1 2
  print('$oneAsString 2');

  // double -> String 注意括號中要有小數(shù)點位數(shù),否則報錯
  String piAsString = 3.14159.toStringAsFixed(2);
  print(piAsString);  // 截取兩位小數(shù), 輸出3.14

  String aString = 1.12618.toStringAsFixed(2);
  // 檢查是否四舍五入,輸出1.13,發(fā)現(xiàn)會做四舍五入
  print(aString);
}
  • num 變量,在使用之前必須賦值
  • num支持運算符 +, -, *, /, %(取模), ~/(取整)
  • num類型的數(shù)據(jù)也能轉(zhuǎn)換類型 toInt(), toDouble(), toString()

2.2Strings類型

// 關(guān)于string 類型測試
void stringFunc() {
  // `Dart字符串` 是由UTF-16編碼單元組成的序列。可以使用`單引號`或`雙引號`創(chuàng)建字符串:
  var s1 = 'hello';
  var s2 = "flutter";
  var s3 = '我是MG';
  var s4 = 'MG';

  print(s1 + s2); //輸出helloflutter
  print(s3*2); //我是MG我是MG

  // 可以使用相鄰的字符串字直接連接在一起 或者 `+操作符` 來連接字符串:
  var s5 = 'Flutter_''MG_'"hello";
  assert(s5 ==
      'Flutter_MG_hello');

  // 另一種創(chuàng)建多行字符串的方法是:`使用帶有單引號` 或 `雙引號的三引號:`
  var s7 = '''
  單引號創(chuàng)建多行字符串 
  注意要各行哦''';
  var s8 = """雙引號創(chuàng)建多行字符串  
  注意要各行哦""";
  print(s7);
  print(s8);

  // 單引號或者雙引號里面嵌套使用引號。
  // 用 {} 來計算字符串中變量的值,需要注意的是如果是表達式需要${表達式}

  // 單引號嵌套雙引號
  String s9 = '$s1 a "MG" ${s3}';
  // 輸出 hello a "MG" 我是MG
  print(s9);
  // 雙引號嵌套單引號
  String s10 = "${s4.toUpperCase()} abc 'MG' $s4.toUpperCase()";
  // 輸出 MG abc 'aaa' MG.toUpperCase(),
  // 可以看出 '$s4.toUpperCase()' 沒有加'{}',導(dǎo)致輸出結(jié)果是'MG.toUpperCase()'
  print(s10);

  String s11 = '這是第一行\(zhòng)n這是第二行';
  String s12 = r'這是第一行\(zhòng)n這是第二行';
  /*輸出
   * 這是第一行
   * 這是第二行
   */
  print(s11);
  print(s12); //輸出 這是第一行\(zhòng)n這是第二行
  print(s12[1]); //輸出 是
}
  • Dart字符串 是由UTF-16編碼單元組成的序列??梢允褂?code>單引號或雙引號創(chuàng)建字符串:
  • 創(chuàng)建多行字符串的方法是:使用帶有單引號雙引號的三引號:
  • {}來計算字符串中變量的值,需要注意的是如果是表達式需要 ${表達式}
  • Dart中字符串的操作是很方便的,可以使用角標的方式獲取字符串某個位置上的字符
  • 字符串之間也可以進行+, *運算
  • 在字符串中如果不需要轉(zhuǎn)義那么在字符串前添加r

2.3Bool 類型

為了表示布爾值,Dart有一個名為 bool 的類型。只有兩個對象具有 bool類型 : 布爾字面值 truefalse,它們都是編譯時常量。因為和我們一般了解一致 這里不做贅述

2.4list類型

//關(guān)于list
void listsFunc() {
  //聲明一個可變list
  var list1 = [1,2,3];
  //聲明一個不可變list
  var list2 = const [1,2,3];
  //list2[1] = 4; // 報錯

  //在list中可以存放不同類型的數(shù)據(jù)
  var list3 = [1, 'name', list2];
  print(list3);

  // spread operator (...)  的用法
  var list4 = [0, ...list1];
  print(list4);  // [0, 1, 2, 3]
  // 注意插入空的情況 那么就需要 `(...?)`
  var list5 ;
  var list6 = [0, ...?list5];
  print(list6);  // [0]

  // list 增刪改查
  // 增加元素
  list1.add(4);
  print(list1);       // [1, 2, 3, 4]
  // 刪除元素
  list1.remove(4);
  print(list1);    // [1, 2, 3]

  // 修改元素
  list1[1] = 100;
  print(list1);     // [1, 100, 3]
  // 查詢
  print(list1.indexOf(3));          // 2 獲取元素的下標
  print(list1.elementAt(1));        // 100
  print(list1.contains(666));       // false
}

2.5Map類型

map 是一個關(guān)聯(lián)鍵和值的對象 (也就是我們所說的字典)

  • map 中的鍵值對是唯一的
  • map 里面的 value 可以相同
  • map 里面的 value 可以為空字符串
//關(guān)于maps
void mapsFunc(){
  //可變map
  var person = {
    // Key:    Value
    'age': 18,
    'name': 'LiHua',
    'hobby': '女',
    'height': 1.85
  };

  //不可變map
  // var student = const {'name', 'zhangsan'};

  print(person); // {age: 18, name: LiHua, hobby: 女, height: 1.85}
  print('${person.keys},${person.values}'); // (age, name, hobby, height),(18, LiHua, 女, 1.85)

  // Map的賦值,中括號中是Key,這里可不是數(shù)組
  person['age'] = '20';
  //Map中的鍵值對是唯一的
  //同Set不同,第二次輸入的Key如果存在,Value會覆蓋之前的數(shù)據(jù)
  person['name'] = 'xiaoming';
  // map里面的value可以相同
  person['hobby'] = 'male';
  // map里面value可以為空字符串
  person['hobby'] = '';
  print(person);    // {age: 20, name: xiaoming, hobby: , height: 1.85}
}

3.Dart中的運算符

Dart中有兩種特殊的運算符,??=, ??;

//運算符
void operatorFunc() {
  //Dart中有兩種特殊的運算符
  //賦值運算 ??=
  //條件表達式 ??

  var a;
  a ??= 10; //如果a為null時則賦值
  a ??= 5; //如果a不為null時則不賦值
  print(a); //輸出 10
  
  var b;
  b = 5;
  print(b ?? a); //輸出5
  
  var c;
  print(c ?? a); //輸出10
  
  // ??如果左邊有值返回左邊,如果左邊沒有值則返回右邊
}

4.Dart中的方法

  • Dart中的方法也是一個對象
  • Dart方法的返回值和參數(shù)類型可以省略
  • Dart方法的執(zhí)行語句只有一句的時候,可以使用箭頭函數(shù) =>

4.1=>箭頭函數(shù)

//Dart的方法
void functionDemo() {
  print(sum(10, 20));
}

// int sum(int a, int b) {
//   return a + b;
// }
//也可以寫成這樣,不過不建議這樣寫
// sum(a, b) => a + b;
//同時 =>函數(shù)也可以加入三目運算
sum(a, b) => a == 20 ? a + b : a - b;

4.2Dart方法的可選參數(shù)

  • Dart方法中有可選參數(shù)并用{}時,傳遞參數(shù)的時候必須帶上形參的名字
  • Dart方法中有可選參數(shù)并用[]時,傳遞參數(shù)的時候參數(shù)的位置時固定的
//Dart的方法
void functionDemo() {
  //必須帶上行參的名字(c,b)順序隨意
  print(sum1(10, c: 1, b: 5));
  //b:1 c:5
  print(sum2(10, 1, 5));
}

//sum1(int a, {b, c}) {
//如果需要指定可選參數(shù)的類型,可以加上?告訴編譯器,后面處理了為空的情況
//sum1(int a, {int? b, int? c}) {
//也可以給可選參數(shù)賦默認值
sum1(int a, {int b = 1, int c = 2}) {
  b ??= 0;
  c ??= 0;
  return a - b + c;
}

//給可選參數(shù)設(shè)定位置,在傳參時b和c的位置不能變
sum2(int a, [int b = 1, int c = 2]) {
  return a - b + c;
}

4.3Dart方法做為參數(shù)傳遞

前文中我們提到過Dart方法是一個對象,那么方法也能作為一個參數(shù)傳遞

void functionDemo() {
  var list = [1,2,3,4];
  //print這個方法作為一個參數(shù)傳入
  forEachFunc(list, print); //輸出1,2,3,4
}

forEachFunc(List list, void func(var element)) {
  //在for循環(huán)內(nèi)部調(diào)用外部傳入的方法
  for (var e in list) func(e);
}

4.4Dart中的匿名函數(shù)

匿名方法顧名思義,就是沒有方法名稱的方法

void functionDemo() {
  var list = [1,2,3,4];
  //匿名函數(shù)作為參數(shù)
  forEachFunc(list, (var e) {
    e ++;
    print(e);
  }); //輸出1,2,3,4
  
  var func = () {
    print('我是一個匿名方法');
  };
  func();
}

forEachFunc(List list, void func(var element)) {
  for (var e in list) func(e);
}

4.5Dart中的閉包closure

  • 閉包:定義在函數(shù)里面的函數(shù)就是閉包,閉包也是一個對象
  • 閉包的作用:它可以訪問外部函數(shù)的局部變量

我們通過下面的示例來理解

//Dart中的閉包
void closureDemo() {
  var func = funcA();
  func();
  func();
  func();
  func();
  //輸出1,2,3,4
  //funA里的count參數(shù)一直被持有

  var func1 = funcA();
  func1();
  func1();
  func1();
  func1();
  //輸出 1,2,3,4

}

funcA() {
  int count = 0;
  return ()=>print(count++); //這個匿名函數(shù)就是一個閉包
}

最后

大家也可以對照Dart官方文檔一起學(xué)習(xí)

?著作權(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)容