Skip to content

第14章:基础实战(新手必练,逐个突破)

实战1:简易计算器(基础语法实战)

14.1 需求分析

  • 实现加减乘除、取模运算
  • 支持用户输入
  • 输出计算结果
  • 处理异常情况(如除数为零)

14.2 核心实现

  • 变量:存储用户输入的操作数和运算符
  • 运算符:实现加减乘除、取模运算
  • 流程控制:使用if-else或switch-case判断运算符类型
  • 输入输出:使用stdin.readLineSync()获取用户输入,print()输出结果
  • 异常处理:处理除数为零的情况

14.3 实操代码讲解与优化

dart
import 'dart:io';

void main() {
  print('=== 简易计算器 ===');
  print('支持操作:+、-、*、/、%');
  print('输入格式:数字1 运算符 数字2(例如:1 + 2)');
  print('输入"exit"退出程序');
  
  while (true) {
    try {
      print('\n请输入计算表达式:');
      var input = stdin.readLineSync();
      
      if (input == 'exit') {
        print('程序已退出');
        break;
      }
      
      if (input == null || input.isEmpty) {
        print('输入不能为空,请重新输入');
        continue;
      }
      
      var parts = input.split(' ');
      if (parts.length != 3) {
        print('输入格式错误,请按照"数字1 运算符 数字2"的格式输入');
        continue;
      }
      
      var num1 = double.parse(parts[0]);
      var operator = parts[1];
      var num2 = double.parse(parts[2]);
      
      double result;
      switch (operator) {
        case '+':
          result = num1 + num2;
          break;
        case '-':
          result = num1 - num2;
          break;
        case '*':
          result = num1 * num2;
          break;
        case '/':
          if (num2 == 0) {
            print('错误:除数不能为零');
            continue;
          }
          result = num1 / num2;
          break;
        case '%':
          result = num1 % num2;
          break;
        default:
          print('错误:不支持的运算符');
          continue;
      }
      
      print('计算结果:$num1 $operator $num2 = $result');
    } catch (e) {
      if (e is FormatException) {
        print('错误:输入的不是有效数字');
      } else {
        print('错误:$e');
      }
    }
  }
}

代码优化

  1. 添加输入验证:检查输入格式是否正确
  2. 异常处理:捕获可能的格式异常和除数为零的情况
  3. 循环结构:使用while循环实现连续计算
  4. 退出功能:支持输入"exit"退出程序

实战2:学生信息管理系统(集合+面向对象实战)

14.4 需求分析

  • 添加学生信息
  • 删除学生信息
  • 查询学生信息
  • 修改学生信息
  • 展示所有学生列表

14.5 核心实现

  • 类与对象:定义Student类存储学生信息
  • List集合:使用List存储学生对象
  • 流程控制:使用switch-case实现菜单选择
  • 方法封装:将添加、删除、查询、修改等功能封装为方法

14.6 实操:完成系统功能,优化代码结构,实现数据校验

dart
import 'dart:io';

class Student {
  final String id;
  final String name;
  final int age;
  final String major;
  
  Student(this.id, this.name, this.age, this.major);
  
  @override
  String toString() {
    return 'ID: $id, 姓名: $name, 年龄: $age, 专业: $major';
  }
}

class StudentManagementSystem {
  List<Student> students = [];
  
  void addStudent() {
    print('\n=== 添加学生 ===');
    print('请输入学生ID:');
    var id = stdin.readLineSync() ?? '';
    
    // 检查ID是否已存在
    if (students.any((student) => student.id == id)) {
      print('错误:该ID已存在');
      return;
    }
    
    print('请输入学生姓名:');
    var name = stdin.readLineSync() ?? '';
    
    print('请输入学生年龄:');
    var ageStr = stdin.readLineSync() ?? '';
    var age = int.tryParse(ageStr);
    if (age == null || age < 0) {
      print('错误:年龄必须是正整数');
      return;
    }
    
    print('请输入学生专业:');
    var major = stdin.readLineSync() ?? '';
    
    var student = Student(id, name, age, major);
    students.add(student);
    print('学生添加成功:$student');
  }
  
  void deleteStudent() {
    print('\n=== 删除学生 ===');
    print('请输入要删除的学生ID:');
    var id = stdin.readLineSync() ?? '';
    
    var index = students.indexWhere((student) => student.id == id);
    if (index == -1) {
      print('错误:未找到该ID的学生');
      return;
    }
    
    var deletedStudent = students.removeAt(index);
    print('学生删除成功:$deletedStudent');
  }
  
  void queryStudent() {
    print('\n=== 查询学生 ===');
    print('请输入要查询的学生ID:');
    var id = stdin.readLineSync() ?? '';
    
    var student = students.firstWhere(
      (student) => student.id == id,
      orElse: () => Student('', '未找到', 0, ''),
    );
    
    if (student.id == '') {
      print('未找到该ID的学生');
    } else {
      print('查询结果:$student');
    }
  }
  
  void modifyStudent() {
    print('\n=== 修改学生信息 ===');
    print('请输入要修改的学生ID:');
    var id = stdin.readLineSync() ?? '';
    
    var index = students.indexWhere((student) => student.id == id);
    if (index == -1) {
      print('错误:未找到该ID的学生');
      return;
    }
    
    var student = students[index];
    print('当前学生信息:$student');
    
    print('请输入新的姓名(回车保持不变):');
    var name = stdin.readLineSync() ?? '';
    if (name.isEmpty) name = student.name;
    
    print('请输入新的年龄(回车保持不变):');
    var ageStr = stdin.readLineSync() ?? '';
    var age = int.tryParse(ageStr);
    if (age == null) age = student.age;
    if (age < 0) {
      print('错误:年龄必须是正整数');
      return;
    }
    
    print('请输入新的专业(回车保持不变):');
    var major = stdin.readLineSync() ?? '';
    if (major.isEmpty) major = student.major;
    
    students[index] = Student(id, name, age, major);
    print('学生信息修改成功:${students[index]}');
  }
  
  void showAllStudents() {
    print('\n=== 所有学生信息 ===');
    if (students.isEmpty) {
      print('暂无学生信息');
      return;
    }
    
    for (var student in students) {
      print(student);
    }
  }
  
  void run() {
    while (true) {
      print('\n=== 学生信息管理系统 ===');
      print('1. 添加学生');
      print('2. 删除学生');
      print('3. 查询学生');
      print('4. 修改学生信息');
      print('5. 展示所有学生');
      print('6. 退出系统');
      
      print('请选择操作(1-6):');
      var choice = stdin.readLineSync();
      
      switch (choice) {
        case '1':
          addStudent();
          break;
        case '2':
          deleteStudent();
          break;
        case '3':
          queryStudent();
          break;
        case '4':
          modifyStudent();
          break;
        case '5':
          showAllStudents();
          break;
        case '6':
          print('系统已退出');
          return;
        default:
          print('错误:无效的选择');
      }
    }
  }
}

void main() {
  var system = StudentManagementSystem();
  system.run();
}

代码优化

  1. 数据校验:添加ID唯一性检查、年龄有效性检查
  2. 用户体验:在修改信息时支持回车保持不变
  3. 错误处理:处理各种异常情况,提供清晰的错误提示
  4. 代码结构:使用类和方法封装功能,提高代码可读性和可维护性

实战3:异步数据请求模拟(异步编程实战)

14.7 需求分析

  • 模拟网络请求
  • 获取数据
  • 处理成功与失败场景
  • 展示数据

14.8 核心实现

  • Future:模拟异步网络请求
  • async/await:简化异步代码
  • 异常处理:处理网络请求失败的情况

14.9 实操:模拟异步请求,实现数据展示与错误提示

dart
import 'dart:async';

// 模拟网络请求
Future<Map<String, dynamic>> fetchUserData(String userId) {
  return Future.delayed(Duration(seconds: 2), () {
    // 模拟网络请求成功
    if (userId == '1' || userId == '2' || userId == '3') {
      return {
        'id': userId,
        'name': 'User $userId',
        'email': 'user$userId@example.com',
        'age': 20 + int.parse(userId),
        'address': 'Address $userId'
      };
    }
    // 模拟网络请求失败
    throw Exception('用户不存在');
  });
}

// 模拟获取多个用户数据
Future<List<Map<String, dynamic>>> fetchMultipleUsers(List<String> userIds) async {
  var futures = userIds.map((id) => fetchUserData(id)).toList();
  return await Future.wait(futures);
}

void main() async {
  print('=== 异步数据请求模拟 ===');
  
  // 测试单个用户数据请求
  print('\n1. 测试单个用户数据请求:');
  try {
    print('正在请求用户1的数据...');
    var user = await fetchUserData('1');
    print('请求成功:');
    print('ID: ${user['id']}');
    print('姓名: ${user['name']}');
    print('邮箱: ${user['email']}');
    print('年龄: ${user['age']}');
    print('地址: ${user['address']}');
  } catch (e) {
    print('请求失败:$e');
  }
  
  // 测试不存在的用户
  print('\n2. 测试不存在的用户:');
  try {
    print('正在请求用户999的数据...');
    var user = await fetchUserData('999');
    print('请求成功:$user');
  } catch (e) {
    print('请求失败:$e');
  }
  
  // 测试多个用户数据请求
  print('\n3. 测试多个用户数据请求:');
  try {
    print('正在请求多个用户的数据...');
    var users = await fetchMultipleUsers(['1', '2', '3']);
    print('请求成功,共获取 ${users.length} 个用户数据:');
    for (var user in users) {
      print('ID: ${user['id']}, 姓名: ${user['name']}, 邮箱: ${user['email']}');
    }
  } catch (e) {
    print('请求失败:$e');
  }
  
  print('\n异步数据请求模拟完成');
}

代码优化

  1. 模拟网络延迟:使用Future.delayed模拟网络请求延迟
  2. 错误处理:使用try-catch捕获和处理异常
  3. 批量请求:使用Future.wait实现多个请求并行执行
  4. 代码结构:将网络请求封装为单独的函数,提高代码可读性

© 2026 编程马·菜鸟教程 版权所有