Wiki
Dart Language Tutorial
Existing English translations were reused. 9 current source blocks remain in Simplified Chinese, without triggering paid translation.
1.Coding Standards
almost exactly the same asC/C++.
- 扩展名: dart语言文件后缀以
.dart结尾 - 入口:dart文件的入口方法为main方法
- 分号:dart文件中绝大部分语句都需要加分号结尾,像
{ }后通常不加分号
2.Dart variables
This section is highly similar toC/C++.
2.1.String type - String
andC/C++instd::stringessentially similar.
Basic usage:
- Keyword: String
- Syntax:
String 属性名 = ‘文本内容’; - Features: Supports double quotes or single quotes, and supports concatenation and template strings
Advanced usage:
- Syntax:
String 属性名 = ‘文本内容$变量名’;orString 变量名 = ‘文本内容${变量名}’; - Note: When the content in the template is an expression, use
${}, whether it is an expression or a variable, it is more recommended to use${}, and try to avoid using$变量名.
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
}
2.2.数字类型-int/double/num
与C/C++中的int,double基本类似.
Basic Syntax
- Scenario: When we need to describe a numeric type, we need to use int/num/double
- Difference: int - integer number, double - decimal, num - can be integer or decimal
- Syntax:
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
}
Essential differences among the three:
num
├── int
└── double
- 👉 num is the parent class
- 👉 int and double are subclasses
Summary table of direct assignment rules:
| Assignment direction | Can it be assigned directly? | Description |
|---|---|---|
| int → num | ✅ Yes | Subclass to superclass |
| double → num | ✅ Yes | Subclass to superclass |
| num → int | ❌ No | May be a double |
| num → double | ❌ No | May be an int |
| int → double | ❌ No | Dart does not convert automatically |
| double → int | ❌ No | Loses the fractional part |
| int → int | ✅ | |
| double → double | ✅ | |
| num → num | ✅ |
Although direct assignment is not possible, it can be converted before assignment. This can be achieved using methods such as toInt() and toDouble() , for example:
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
}
2.3.Boolean type - bool
Similar toC/C++inboolis basically similar.
- Scenario: When we need an attribute to represent whether something is currently true or false, we need to use the bool keyword to declare it.
- Requirement: Declare whether you have already finished your homework.
- Syntax:
bool 属性名 = true/false;
void main()
{
bool isFinishWork = false;
print('我的工作完成状态为:$isFinishWork'); //Output: 我的工作完成状态为:false
isFinishWork = true;
print('我的工作完成状态为:$isFinishWork'); //Output: 我的工作完成状态为:true
}
2.4.List Type - List
2.4.1.List
Similar toC/C++the vectors inSTL.(Note, unlikestd::vectorandstd::list) Andstd::vectorwe often use it as不定长数组, so when you don't understandstd::vectorjust treat it as an advanced数组and that's fine.
本节肯定讲不完List的所有用法,但是大多数常用的用法都会讲到,你忘记了可以随时去查文档就行,不用每种用法都硬背下来,用的多的用法自然你就记住了,现在你只需要学完一遍,并知道有那么个东西即可.
Basic usage:
- 场景:当一个变量需要存储多个值的时候,可以使用列表类型List
- 需求:一个班级的学生用List存储,支持对学生的查找、新增、删除、循环
- 语法:List 属性名 = [‘学生1’, ‘学生2’];
Common usage 1:
- Append at tail -
add(内容) - Append a list at tail -
addAll(列表) - Delete the first matching content -
remove(内容) - Delete the last -
removeLast() - Delete data within index range -
removeRange(start,end)Note: end is not included in the deletion range
Common usage 2:
Below, several methods and properties will be listed. If you have studied object-oriented programming, you definitely know what they are; if not, I'll briefly explain first:
类-class的声明与定义
对象-class类型的实例,(不好理解也可以理解为class类型的变量)
方法-class里的函数
属性-class里的变量
- Loop (method) -
forEach((item) {}); - Whether all conditions are met (method) -
every((item) { return 布尔值 }); - Filter out data that meets the conditions (method) -
where((item) { return 布尔值 }); - Length of list (property) -
length - Last element (property) -
last - First element (property) -
first - Whether it is empty (property) -
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 (因为列表中有数据)
}
2.4.2.main function entry parameters
In addition to the above code, it can be seen thatvoid main(List<String> args)now contains a parameter, which is actually similar toC/C++inint main(int argc, char* argv[])
| 对比点 | C/C++ | Dart |
|---|---|---|
| 参数个数 | argc |
args.length |
| 参数数组 | argv[] |
List<String> |
| 是否包含程序名 | ✅ argv[0] 是程序名 | ❌ 不包含 |
| 类型安全 | ❌ char* | ✅ String |
| 内存管理 | 手动 | 自动 |
For example
dart run app.dart hello world
At this time
args[0] = "hello"
args[1] = "world"
2.5.Dictionary type - Map
Similar to C++std::map.
Basic usage:
- One key corresponds to one value
- Syntax 1: Map propertyName = { key: value };
- Syntax 2:
字典[key] 可以取值和赋值
Common usage:
- Loop-
forEach - Add a dictionary-
addAll - Whether it contains a certain key-
containsKey - Delete a certain key-
remove - Clear-
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);
}
2.6.Dynamic Type - dynamic
Similar to C++std::any
- Definition: In the Dart language, dynamic is used to declare a dynamic type.
- Feature: Allows a variable to freely change its type at runtime, while bypassing compile-time static checks.
- Syntax 1:
dynamic 属性名 = 值;
void main(List<String> args)
{
// dynamic 可以动态的改变类型
dynamic name = "张三";
print(name);
name = 123;
print(name);
}
Only when you yourself are 100% sure that what you wrote is correct should you use dynamic; otherwise, do not use dynamic, or many errors may occur.
2.7.Automatically inferred type - var
similar to C/C++auto.
This keyword can automatically deduce the type of a variable.
- Keyword: var
- Syntax:
var 变量名 = 值/表达式; - Note: For a variable declared with var, its type is determined after the first assignment, and values of other types cannot be assigned afterward.
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
}
Dynamic Types in Dart - The Difference Between dynamic and var:
- dynamic: The type can be freely changed at runtime, with no compile-time checking; methods and properties can be called directly.
- var: The type is inferred from the initial value; once the type is determined, it is fixed, with compile-time checking, and only the inferred properties and methods are allowed.
2.8.常量声明-const/final
2.8.1.const
Similar to 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!
}
2.8.2.final
similar to 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
}
- Variable: When you need to store changing data, you need to use var to declare a variable.
- Compile-time constant: When you need to store unchanging data that is determined at compile time, you need to use const to declare a constant.
- Runtime constant: When you need to store unchanging data that is determined only at runtime, you need to use final to declare a constant.
| Concept | Dart | C++ | Compile-time constant | Runtime-determinable | Object immutability |
|---|---|---|---|---|---|
| Assigned only once | final |
const |
❌ | ✅ | ❌ |
| Compile-time constant | const |
constexpr |
✅ | ❌ | ✅ (Dart is stronger) |
| Read-only variable | No exact equivalent | const |
❌ | ✅ | ❌ |
3.Null safety mechanism
- Definition: In the Dart language, runtime null pointer issues are exposed in advance through compile-time static checks
- Feature: Moves null pointer exceptions from runtime to compile time, reducing production crashes
Common null safety operators
| Operator | Symbol | Function | Example |
|---|---|---|---|
| Nullable type | ? |
Declare a nullable variable | String? → Allows String or null |
| Safe call | ?. |
Skips the operation when the object is null and returns null | user?.name → Returns null if user is null |
| Not-null assertion | !. |
The developer guarantees that the variable is not null (otherwise it crashes at runtime) | name!.length → Asserts that name is not null |
| Null coalescing | ?? |
Returns the default value on the right when the left side is null | name ?? "Guest" → Returns "Guest" when name is null |
| Null coalescing assignment | ??= |
Assigns a value only when the variable is null | name ??= "Guest" |