在线学习平台
本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 105 课,共 107 课。
挑战
简单让我们构建一个电子学习平台,用来管理课程和学生,并跟踪学习进度!你将结合结构体、接口、组合和多态,创建一个完整的系统,让学生能够注册课程并完成课时。
你将把代码分布在 5 个文件中:
lesson.go:定义一个Lesson结构体,用来表示单个学习单元。每个课时都有一个ID、Title和Duration(以分钟为单位)。添加一个NewLesson构造函数,返回指向 Lesson 的指针。course.go:创建一个Course结构体,其中包含ID、Title、Instructor,以及一个由*Lesson指针组成的切片。添加一个NewCourse构造函数和一个AddLesson方法。还要实现一个TotalDuration() int方法,返回课程中所有课时的总时长。student.go:定义一个包含ID、Name和Email字段的Student结构体。添加一个NewStudent构造函数。enrollment.go:进度跟踪功能将在这里实现。创建一个Enrollment结构体,将学生和课程关联起来,并跟踪学生已完成的课时。它应包含:- 一个指向
Student的指针 - 一个指向
Course的指针 - 一个
CompletedLessons字典(课时 ID 对应布尔值)
定义一个
Progressable接口,其中包含一个Progress() float64方法,返回百分比(0.0 到 100.0)。为 Enrollment 实现以下方法:
NewEnrollment(student *Student, course *Course) *Enrollment:构造函数,用于初始化一个空的已完成课时字典CompleteLesson(lessonID string) string:将课时标记为已完成。如果课程中不存在该课时,则返回lesson not found;如果已经完成,则返回already completed;成功时返回completedProgress() float64:返回已完成课时的百分比(已完成数量/总数量 * 100);如果课程没有课时,则返回 0.0
- 一个指向
main.go:构建平台并处理选课操作。读取课程的 ID、标题和讲师。然后读取课时数量,以及每个课时的 ID、标题和时长。读取学生的 ID、姓名和电子邮箱。创建一个选课记录,将学生和课程关联起来。
然后读取操作数量。每个操作可以是
complete [lessonID]或progress。对于完成课时的操作,打印结果消息。对于进度操作,将进度格式化为小数点后一位,并在末尾加上百分号后打印。
输入内容如下:
- 课程 ID、标题、讲师(3 行)
- 课时数量,然后是每个课时的 ID、标题和时长(每个课时 3 行)
- 学生 ID、姓名、电子邮箱(3 行)
- 操作数量,然后是每个操作(每个操作 1 行)
例如,给定以下输入:
C001
Go Fundamentals
Jane Smith
3
L001
Variables
30
L002
Functions
45
L003
Structs
60
S001
Alice
alice@learn.com
5
progress
complete L001
progress
complete L001
complete L002输出应为:
0.0%
completed
33.3%
already completed
completed再例如,给定以下输入:
C100
Python Basics
Bob Teacher
2
L100
Intro
20
L101
Loops
40
S100
Charlie
charlie@edu.com
4
complete L999
complete L100
complete L101
progress输出应为:
lesson not found
completed
completed
100.0%注意,Enrollment 结构体通过组合将学生和课程关联起来,而 Progressable 接口允许任何类型报告其完成状态。这种设计便于扩展。你可以使用相同的接口,为单个课时或整个学习路径添加进度跟踪功能!
亲手试试
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 用于读取一行的辅助函数
readLine := func() string {
scanner.Scan()
return strings.TrimSpace(scanner.Text())
}
// 读取课程信息
courseID := readLine()
courseTitle := readLine()
courseInstructor := readLine()
// TODO:使用 NewCourse 创建课程
_ = courseID
_ = courseTitle
_ = courseInstructor
// 读取课的数量
numLessons, _ := strconv.Atoi(readLine())
// TODO:读取每节课并添加到课程中
for i := 0; i < numLessons; i++ {
lessonID := readLine()
lessonTitle := readLine()
lessonDuration, _ := strconv.Atoi(readLine())
// TODO:创建课并添加到课程中
_ = lessonID
_ = lessonTitle
_ = lessonDuration
}
// 读取学生信息
studentID := readLine()
studentName := readLine()
studentEmail := readLine()
// TODO:使用 NewStudent 创建学生
_ = studentID
_ = studentName
_ = studentEmail
// TODO:创建关联学生与课程的选课记录
// 读取操作数量
numOps, _ := strconv.Atoi(readLine())
// 处理每个操作
for i := 0; i < numOps; i++ {
operation := readLine()
if operation == "progress" {
// TODO:调用 Progress(),并以 "%.1f%%" 格式输出
fmt.Println("0.0%") // 替换为实际进度
} else if strings.HasPrefix(operation, "complete ") {
lessonID := strings.TrimPrefix(operation, "complete ")
// TODO: 调用 CompleteLesson 并打印结果
_ = lessonID
fmt.Println("") // 替换为实际结果
}
}
}
面向对象编程中的所有课
自己练习: Go 在线编译器