Flutter(四)Dart语法 空安全 运算符 流程控制

空安全

scss 复制代码
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]
}

运算符

scss 复制代码
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!
}

流程控制

dart 复制代码
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"); // 个位正数
}

流程控制

dart 复制代码
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"); // 个位正数
}
相关推荐
许彰午1 小时前
政务督办的分合模式:主办协办的并发审批
前端·javascript·政务
用户69371750013841 小时前
AI时代,程序员该往哪走?
前端·后端
ttwuai1 小时前
GoFrame 后台日志清空失败:无 WHERE 删除为什么被拦住
前端·golang
易筋紫容1 小时前
创建型模式:对象的诞生艺术
开发语言·前端·javascript
半句唐诗2 小时前
我是如何通过 Access Token 成功发布第一个 npm 包的
前端·npm·node.js
程序员黑豆2 小时前
鸿蒙应用开发:@Provider 与 @Consumer 跨组件双向同步详解
前端·harmonyos
paopaokaka_luck2 小时前
基于springboot3+vue3的智能文库平台(AI智能搜索、AI智能汇总、实时在线状态展示、多格式文档预览与富文本编辑、Echarts图形化分析)
前端·网络·spring boot·网络协议·echarts
牧艺2 小时前
cos-design PhotoAlbum:用 CSS 3D 做一个「能翻页」的实体相册
前端·css·交互设计
洪贺2 小时前
从原始采样到可缩放心电图:用 h5ECG 绘制自己的 ECG
前端