第 4 節

Dart語言教程

0瀏覽次數0訪問次數--跳出率--平均停留

代碼規範

幾乎和C/C++一模一樣.

  • 擴展名: dart語言文件後綴以.dart結尾
  • 入口:dart文件的入口方法為main方法
  • 分號:dart文件中絕大部分語句都需要加分號結尾,像 { } 後通常不加分號

Dart的變量

該節與C/C++高度相似.

字符串類型-String

C/C++中的std::string基本類似.

基礎用法:

  • 關鍵字:String
  • 語法:String 属性名 = ‘文本内容’;
  • 特點:引號支持雙引號或者單引號,支持拼接及模板字符串

進階用法:

  • 語法:String 属性名 = ‘文本内容$变量名’;String 变量名 = ‘文本内容${变量名}’;
  • 注意:當存在模板中的內容是一個表達式的時候需要使用${}, 不管是表達式還是變量,都更推薦使用${},儘量不要用$变量名了.
void main()
{
  String name = 'Alice';
  print(name); // Output: Alice

  name = 'Bob';
  print(name); // Output: Bob

  String greeting = 'Hello, ${name}?$name!';
  print(greeting); // Output: Hello, Bob?Bob!

  String when = 'it is ${DateTime.now()},now';
  print(when); // Output: it is 2026-02-16 14:46:17.818262,now
}

數字類型-int/double/num

C/C++中的int,double基本類似.

基礎語法

  • 場景:當我們需要描述一個數字類型的時候,需要使用int/num/double
  • 區別:int-整型數字,double-小數 , num-可整型可小數
  • 語法:int/num/double 属性名 = 数值;
void main()
{
  int age = 23;
  print(age); // Output: 23

  age = 24;
  print(age); // Output: 24

  double height = 1.78;
  print(height); // Output: 1.78

  height = 1.80;
  print(height); // Output: 1.8

  num weight = 90.5;
  print(weight); // Output: 90.5

  weight = 76;
  print(weight); // Output: 76
}

三者本質區別:

num
 ├── int
 └── double
  • 👉 num 是父類
  • 👉 int 和 double 是子類

直接賦值規則總表:

賦值方向是否可以直接賦值說明
int → num✅ 可以子類給父類
double → num✅ 可以子類給父類
num → int❌ 不行可能是 double
num → double❌ 不行可能是 int
int → double❌ 不行Dart 不自動轉
double → int❌ 不行會丟失小數
int → int
double → double
num → num

雖然無法直接賦值,但是可以轉化後再賦值.可以利用toInt()toDouble()等方法來實現,如:

void main()
{
  int a = 10;
  print(a); // Output: 10

  double b = 3.14;
  print(b); // Output: 3.14
  
  // double赋值给double
  double c = b;
  print(c); // Output: 3.14

  // int赋值给double
  b = a.toDouble();
  print(b); // Output: 10.0

  num d = 5.6;
  print(d); // Output: 5.6

  // num赋值给int
  a = d.toInt();
  print(a); // Output: 5

}

布爾類型-bool

C/C++中的bool基本類似.

  • 場景:當我們需要一個屬性來表示當前為真(true)或假(false)的時候,需要使用bool關鍵字聲明
  • 需求:聲明當前自己是否已經完成作業
  • 語法:bool 属性名 = true/false;
void main()
{
  bool isFinishWork = false;
  print('我的工作完成状态为:$isFinishWork'); //Output: 我的工作完成状态为:false
  
  isFinishWork = true;
  print('我的工作完成状态为:$isFinishWork'); //Output: 我的工作完成状态为:true
}

列表類型-List

List

C/C++中的STL向量std::vector基本類似.(注意,和std::list並不像) 而std::vector我們經常把他用作不定长数组,所以你不理解std::vector的時候把他當作一個高級的数组也可以.

本節肯定講不完List的所有用法,但是大多數常用的用法都會講到,你忘記了可以隨時去查文檔就行,不用每種用法都硬背下來,用的多的用法自然你就記住了,現在你只需要學完一遍,並知道有那麼個東西即可.

基礎用法:

  • 場景:當一個變量需要存儲多個值的時候,可以使用列表類型List
  • 需求:一個班級的學生用List存儲,支持對學生的查找、新增、刪除、循環
  • 語法:List 屬性名 = ‘學生1’, ‘學生2’;

常用用法1:

  • 在尾部添加-add(内容)
  • 在尾部添加一個列表-addAll(列表)
  • 刪除滿足內容的第一個-remove(内容)
  • 刪除最後一個-removeLast()
  • 刪除索引範圍內數據-removeRange(start,end) 注意:end不包含在刪除範圍內

常用用法2:

下面會列舉幾個方法與屬性,學過面向對象你肯定知道是啥,如果沒學過,我就先簡單說一下:

类-class的声明与定义
对象-class类型的实例,(不好理解也可以理解为class类型的变量)
方法-class里的函数
属性-class里的变量
  • 循環(方法)-forEach((item) {});
  • 是否都滿足條件(方法)-every((item) { return 布尔值 });
  • 篩選出滿足條件的數據(方法)-where((item) { return 布尔值 });
  • 列表的長度(屬性)-length
  • 最後一個元素(屬性)-last
  • 第一個元素(屬性)-first
  • 是否為空(屬性)-isEmpty
void main(List<String> args) 
{
  List students = ["张三", "李四", "王五"];
  print(students); // Output: [张三, 李四, 王五]

  students.add("新同学"); // 在尾部进行添加
  print(students); // Output: [张三, 李四, 王五, 新同学]s

  students.addAll(["新来的同学1", "新来的同学2"]); // 在尾部添加一个列表
  print(students); // Output: [张三, 李四, 王五, 新同学, 新来的同学1, 新来的同学2]

  students.add("新同学"); // 在尾部进行添加
  print(students); // Output: [张三, 李四, 王五, 新同学, 新来的同学1, 新来的同学2, 新同学]

  students.remove("新同学"); // 删除满足内容的第一个
  print(students); // Output: [张三, 李四, 王五, 新来的同学1, 新来的同学2, 新同学]

  // 删除最后一个同学
  students.removeLast(); // 删除最后一个
  print(students); // Output: [张三, 李四, 王五, 新来的同学1, 新来的同学2]

  // 删除前两个同学
  // start开始的索引 end结束的索引-不包含在删除范围内
  students.removeRange(0, 2);
  print(students); // Output: [王五, 新来的同学1, 新来的同学2]

  // forEach针对每个列表每个数据进行操作
  students.forEach((item) 
  {
    // 书写逻辑
    print(item); // Output: 王五
                 //         新来的同学1
                 //         新来的同学2
  });

  // 是不是所有的同学都以新为开头
  bool isAllStartWithNew = students.every((item) 
  {
    return item.toString().startsWith("新"); // 返回一个条件
  });
  print(isAllStartWithNew); // Output: false (因为王五不以新开头,需要满足所有的同学都以新开头才会返回true)

  // 筛选出所有的以新开头的同学呢
  List newStudents = students.where((item) 
  {
    return item.toString().startsWith("新");
  }).toList();
  print(newStudents); // Output: [新来的同学1, 新来的同学2]


  // List常用的一些属性 方法() .属性
  // 列表的长度
  print(students.length); // Output: 3

  // 列表的第一个
  print(students.first); // Output: 王五

  // 列表的最后一个
  print(students.last); // Output: 新来的同学2

  // 列表是否是空的
  print(students.isEmpty); // Output: false (因为列表中有数据)
}
main函數入口參數

除了上面的代碼外可以看到void main(List<String> args)裡有參數了,這個其實類似C/C++裡的int main(int argc, char* argv[])

對比點C/C++Dart
參數個數argcargs.length
參數數組argv[]List<String>
是否包含程序名✅ argv0 是程序名❌ 不包含
類型安全❌ char*✅ String
內存管理手動自動

例如

dart run app.dart hello world

此時

args[0] = "hello"
args[1] = "world"

字典類型-Map

類似C++的std::map.

基礎用法:

  • 一個key對應一個value
  • 語法1:Map 屬性名 = { key: value };
  • 語法2: 字典[key] 可以取值和赋值

常用用法:

  • 循環-forEach
  • 在添加一個字典-addAll
  • 是否包含某個key-containsKey
  • 刪除某個key-remove
  • 清空-clear
void main(List<String> args) 
{
  Map transMap = {"lunch": '午饭', "morning": "早上", "hello": '你好'};
  print(transMap);
  // 通过英文找到对应中文的描述
  print(transMap["morning"]);
  transMap["hello"] = "你非常好";
  print(transMap["hello"]);
  // 字典里面有很多对应关系
  transMap.forEach((key, value) {
    print("$key,$value");
  });
  // addAll 给当前字典添加一个字典
  transMap.addAll({"fine": "非常好"});
  print(transMap);
  // containesKey判断字典中是否包含某个key
  print(transMap.containsKey("fine"));

  transMap.remove("fine");
  print(transMap);

  // 清空字典
  transMap.clear();
  print(transMap);
}

動態類型-dynamic

類似C++的std::any

  • 定義:Dart語言中,dynamic用來聲明動態類型
  • 特點:允許變量運行時自由改變類型, 同時繞過編譯時的靜態檢查
  • 語法1:dynamic 属性名 = 值;
void main(List<String> args) 
{
  // dynamic 可以动态的改变类型
  dynamic name = "张三";
  print(name);
  name = 123;
  print(name);
}

只有你自己100%認為你寫的是對的,再用dynamic,否則別用dynamic,不然可能會出現很多錯誤.

自動推導類型-var

類似C/C++的auto.

這個關鍵字可以自動推導變量的類型.

  • 關鍵字:var
  • 語法:var 变量名 = 值/表达式;
  • 注意:使用var聲明的變量,其類型在第一次賦值之後確定,不能再賦值其他類型的值
void main(List<String> args) 
{
  var name = '张三';
  print(name); // Output: 张三

  name = '李四';
  print(name); // Output: 李四

  var age = 30;
  print(age); // Output: 30

  var isStudent = true;
  print(isStudent); // Output: true

  var height = 1.75;
  print(height); // Output: 1.75
}

Dart中的動態類型-dynamic和var的區別:

  • dynamic: 運行時可自由改變類型,無編譯檢查,方法和屬性直接調用
  • var: 根據初始值進行推斷類型,確定類型後類型確定,有編譯檢查,僅限推斷的屬性和方法

常量聲明-const/final

const

類似C++的constexpr.

  • 關鍵字:const
  • 語法:const 屬性名 = 值/表達式;
  • 特點:const是代碼編譯前被確定,不允許表達式中有變量存在,必須為常量或者固定值
void main(List<String> args) 
{
  const int a = 10;
  const double b = 3.14;
  const String c = "Hello, Dart!";

  print("Value of a: ${a}"); // Output: Value of a: 10
  print("Value of b: ${b}"); // Output: Value of b: 3.14
  print("Value of c: ${c}"); // Output: Value of c: Hello, Dart!
}
final

類似C++的const.

  • 關鍵字:final
  • 語法:final 屬性名 = 值/表達式;
  • 特點:final變量在運行時被初始化,其值設置後不可更改
void main(List<String> args) 
{
  final time = DateTime.now();
  print('Current time: $time'); // Current time: 2026-02-16 20:53:53.045010
}
  • 變量:當需要存儲一個變化的數據需要使用var來聲明變量
  • 編譯時常量:當需要存儲一個不變的數據,且在編譯時就確定,需要使用const聲明常量
  • 運行時常量:當需要存儲一個不變的數據,但是在運行時才確定,需要使用final聲明常量
概念DartC++是否編譯期常量是否可運行期確定是否對象不可變
只賦值一次finalconst
編譯期常量constconstexpr✅(Dart更強)
只讀變量無完全等價const

空安全機制

  • 定義:在Dart語言中,通過編譯靜態檢查將運行時空指針提前暴露
  • 特點:將空指針異常從運行時提前至編譯時,減少線上崩潰

常用空安全操作符

操作符符號作用示例
可空類型?聲明可空變量String? → 允許 String 或 null
安全訪問?.對象為 null 時跳過操作,返回 nulluser?.name → 若 user 為 null 則返回 null
非空斷言!.開發者保證變量非空(否則運行時崩潰)name!.length → 斷言 name 非空
空合併??左側為 null 時返回右側默認值name ?? "Guest" → name 為 null 時返回 "Guest"
空合併賦值??=變量為 null 時才賦值name ??= "Guest"
音乐页