空安全
void main(List<String> args) {
// 可空类型 变量可以不赋值,默认为null
int? a ;
print(a);//null
print(a.runtimeType);//NULL
a = 20;
print(a.runtimeType);//int
a = null;
//安全访问
// 会报错
// print(a + 30);
String? s = null;
// 如果为空,则不做操作,直接返回null
print(s?.startsWith("h"));
s = "hello";
print(s?.startsWith("h"));// true
// !表示一定有值。否则会报错
print(s!.startsWith("h"));// true
// 空合并
s = null;
print(s ?? "nice to meet you");
// 空赋值 ??= 只有变量为null时才赋值
String? name;
name ??= "default";
print(name); // default
// name 已非空,??= 不会覆盖
String? name2 = "existing";
name2 ??= "new value";
print(name2); // existing 已经有值,不会覆盖
// late 关键字 延迟初始化
// 声明时不赋值,但保证在使用前一定会被赋值(非空)
late String description;
description = "This is a late variable";
print(description);
// 如果未赋值就使用会抛出 LateInitializationError
// late String uninitialized;
// print(uninitialized); // 报错
// required 命名参数 必须传值的命名参数
void createUser({required String name, int? age}) {
print("User: $name, Age: ${age ?? 'unknown'}");
}
createUser(name: "Alice");
createUser(name: "Bob", age: 25);
// 类型提升 流分析自动将可空类型提升为非空类型
// 模拟一个运行时可能为null的值
int? nullableValue = DateTime.now().millisecond > 500 ? 10 : null;
if (nullableValue != null) {
// 在这个作用域中,nullableValue 被自动提升为 int 类型
// 可以直接使用,无需 ! 或 ?.
int nonNull = nullableValue + 5;
print(nonNull); // 可能为 15
}
// List<String>? vs List<String?>
// List<String>? 列表本身可空,列表元素非空
List<String>? nullableList;
print(nullableList); // null
nullableList = ["a", "b"];
print(nullableList); // [a, b]
// List<String?> 列表本身非空,列表元素可空
List<String?> listWithNullableElements = ["hello", null, "world"];
print(listWithNullableElements); // [hello, null, world]
// 级联 ?.. 安全的级联操作
String? nullableStr;
// 如果 nullableStr 为 null,则不会执行任何操作
nullableStr
?..toUpperCase()
..toLowerCase();
print(nullableStr); // null
nullableStr = "hello";
// 赋值后 nullableStr 被提升为 String,?.. 不再需要
nullableStr
..toUpperCase()
..toLowerCase();
print(nullableStr); // hello
// ?.. 与 .. 组合使用
List<int>? numbers;
numbers
?..add(1)
..add(2)
..add(3);
print(numbers); // null numbers 为 null,?.. 后面的级联不会执行
numbers = [];
// numbers 已被赋值为非空列表,?.. 不再必要
numbers
..add(1)
..add(2)
..add(3);
print(numbers); // [1, 2, 3]
}
运算符
void main(List<String> args) {
// int和double可以直接运算
int a = 10;
double b= 3.14;
double squre = a * b;
print(squre);
int c = 100;
int d = 3;
double e = c / d;
print(e); //33.3333
// 整除结果是int
// double f = c ~/ d;
int f = c ~/ d;
print(f);
int g = c % d;
print(g);// 1
int h = -20 % 3;
print(h);// 1 -20 = 3 * -7 + 3
// 比较运算符 == != < > <= >=
print(10 == 10); // true
print(10 != 5); // true
print(10 > 5); // true
print(10 < 5); // false
print(10 >= 10); // true
print(10 <= 9); // false
// 逻辑运算符 && || !
bool isAdult = DateTime.now().millisecond > 500;
bool hasTicket = false;
print(isAdult && hasTicket); // false 且
print(isAdult || hasTicket); // true/false 或
print(!isAdult); // 取反
// 复合赋值运算符 += -= *= /= ~/= %=
int score = 50;
score += 10; // 60
print(score);
score -= 5; // 55
print(score);
score *= 2; // 110
print(score);
double amount = 100.0;
amount /= 3; // 33.333...
print(amount);
int points = 100;
points ~/= 3; // 33
print(points);
int remain = 100;
remain %= 7; // 2
print(remain);
// 自增自减 ++ -- 前置与后置
int count = 5;
print(count++); // 5 后置:先返回原值再加1
print(count); // 6
print(++count); // 7 前置:先加1再返回
print(count); // 7
print(count--); // 7 后置:先返回原值再减1
print(count); // 6
print(--count); // 5 前置:先减1再返回
print(count); // 5
// 位运算符 & | ^ ~ << >>
int bitA = 5; // 0101
int bitB = 3; // 0011
print(bitA & bitB); // 1 按位与 0001
print(bitA | bitB); // 7 按位或 0111
print(bitA ^ bitB); // 6 按位异或 0110
print(~bitA); // -6 按位取反
print(bitA << 1); // 10 左移 1010
print(bitA >> 1); // 2 右移 0010
// 类型测试运算符 is is! as
Object name = "hello";
print(name is String); // true
print(name is! int); // true
// as 类型转换:父类转为子类 或 可空转非空
String str = name as String;
print(str); // hello
String? nullableStr = "world";
String definiteStr = nullableStr as String;
print(definiteStr); // world
// 条件/三元表达式 ? :
int age = 20;
String result = age >= 18 ? "成年" : "未成年";
print(result); // 成年
// 级联符号 .. 链式调用同一对象
List<int> numbers = [];
numbers
..add(1)
..add(2)
..add(3);
print(numbers); // [1, 2, 3]
// 可空级联 ?.. 对象为null时跳过所有操作
List<int>? nullableList;
nullableList
?..add(1)
..add(2);
print("nullableList $nullableList"); // null 对象为null,所有级联操作被跳过
// 展开运算符 ... ...?
List<int> list1 = [1, 2, 3];
List<int> list2 = [0, ...list1, 4];
print(list2); // [0, 1, 2, 3, 4]
List<int>? maybeList;
List<int> list3 = [0, ...?maybeList];
print(list3); // [0] maybeList为null时展开为空
// 字符串插值
String greeting = "Hello";
int year = 2026;
print("$greeting, $year!"); // Hello, 2026!
print("year is ${year + 1}"); // year is 2027
// 符号级联 .. 可用于字符串拼接以外的链式操作
StringBuffer buffer = StringBuffer()
..write("Dart ")
..write("is ")
..writeln("awesome!");
print(buffer.toString()); // Dart is awesome!
}
流程控制
void main(List<String> args) {
var a = 20;
if (a > 10) {
print(" a > 10");
} else {
print("a < 10");
}
switch (a) {
case 30:
print("30");
break;
case 20:
print(20);
break;
default:
print("not found");
}
var begin = 0;
var total = 0;
while (begin < 101) {
total += begin;
begin += 1;
}
print("total is $total");
// break 跳出循环
begin = 0;
while (begin < 100) {
print("begin is $begin");
begin += 1;
if (begin == 3) {
break;
}
}
// continue 继续循环
print("continue");
begin = 0;
while (begin < 5) {
begin += 1;
if (begin == 3) {
continue;
}
print("begin is $begin");
}
int sum = 0;
for (int index = 0; index < 101; index++) {
sum += index;
}
print("sum is $sum"); // sum is 5050
// for-in 遍历集合
for (var item in [1, 2, 3]) {
print("item is $item");
}
// do-while 至少执行一次
int n = 0;
do {
n += 1;
} while (n < 3);
print("n is $n"); // 3
// 集合 if 在列表字面量中使用条件
bool isReady = true;
var list = [
"a",
"b",
if (isReady) "c",
];
print(list); // [a, b, c]
// 集合 for 在列表字面量中使用循环
var list2 = [
0,
for (var i = 1; i <= 3; i++) i,
];
print(list2); // [0, 1, 2, 3]
// 集合 for 遍历另一个集合生成新集合
var original = [1, 2, 3];
var doubled = [for (var v in original) v * 2];
print(doubled); // [2, 4, 6]
// 标签 break 跳出外层循环
outer:
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break outer; // 直接跳出外层循环
}
print("i=$i, j=$j");
}
}
// 标签 continue 跳过外层当前迭代
outer2:
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
if (j == 1) {
continue outer2; // 跳过外层本次循环,进入下一次
}
print("outer2: i=$i, j=$j");
}
}
// assert 断言 仅在调试模式下生效,发布构建中被忽略
var value = 10;
assert(value >= 0, "value must be non-negative");
print("assert passed");
// switch 表达式(Dart 3) 有返回值,无需 break
var color = "red";
var result = switch (color) {
"red" => "停止",
"yellow" => "注意",
"green" => "通行",
_ => "未知",
};
print("result is $result"); // 停止
// switch 表达式配合模式匹配
var number = 5;
var type = switch (number) {
< 0 => "负数",
0 => "零",
> 0 && <= 9 => "个位正数",
>= 10 => "两位及以上",
_ => "未知",
};
print("type is $type"); // 个位正数
}
流程控制
void main(List<String> args) {
var a = 20;
if (a > 10) {
print(" a > 10");
} else {
print("a < 10");
}
switch (a) {
case 30:
print("30");
break;
case 20:
print(20);
break;
default:
print("not found");
}
var begin = 0;
var total = 0;
while (begin < 101) {
total += begin;
begin += 1;
}
print("total is $total");
// break 跳出循环
begin = 0;
while (begin < 100) {
print("begin is $begin");
begin += 1;
if (begin == 3) {
break;
}
}
// continue 继续循环
print("continue");
begin = 0;
while (begin < 5) {
begin += 1;
if (begin == 3) {
continue;
}
print("begin is $begin");
}
int sum = 0;
for (int index = 0; index < 101; index++) {
sum += index;
}
print("sum is $sum"); // sum is 5050
// for-in 遍历集合
for (var item in [1, 2, 3]) {
print("item is $item");
}
// do-while 至少执行一次
int n = 0;
do {
n += 1;
} while (n < 3);
print("n is $n"); // 3
// 集合 if 在列表字面量中使用条件
bool isReady = true;
var list = [
"a",
"b",
if (isReady) "c",
];
print(list); // [a, b, c]
// 集合 for 在列表字面量中使用循环
var list2 = [
0,
for (var i = 1; i <= 3; i++) i,
];
print(list2); // [0, 1, 2, 3]
// 集合 for 遍历另一个集合生成新集合
var original = [1, 2, 3];
var doubled = [for (var v in original) v * 2];
print(doubled); // [2, 4, 6]
// 标签 break 跳出外层循环
outer:
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break outer; // 直接跳出外层循环
}
print("i=$i, j=$j");
}
}
// 标签 continue 跳过外层当前迭代
outer2:
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
if (j == 1) {
continue outer2; // 跳过外层本次循环,进入下一次
}
print("outer2: i=$i, j=$j");
}
}
// assert 断言 仅在调试模式下生效,发布构建中被忽略
var value = 10;
assert(value >= 0, "value must be non-negative");
print("assert passed");
// switch 表达式(Dart 3) 有返回值,无需 break
var color = "red";
var result = switch (color) {
"red" => "停止",
"yellow" => "注意",
"green" => "通行",
_ => "未知",
};
print("result is $result"); // 停止
// switch 表达式配合模式匹配
var number = 5;
var type = switch (number) {
< 0 => "负数",
0 => "零",
> 0 && <= 9 => "个位正数",
>= 10 => "两位及以上",
_ => "未知",
};
print("type is $type"); // 个位正数
}