go实现LinkTable版menu程序

L13124 2022-04-13 11:59:13

一.LinkNode定义

指令结点及其接口和方法

package menu

//指令结点
type LinkNode struct {
	next    *LinkNode
	command string
	cmdDo   CallBack
}

type CallBack interface {
	do()
}

func Create(command string, cmdDo CallBack) *LinkNode {
	newCommand := &LinkNode{
		next:    nil,
		command: command,
		cmdDo:   cmdDo,
	}
	return newCommand
}

func (i *LinkNode) do() {
	i.cmdDo.do()
}

func (i *LinkNode) nextNode() *LinkNode {
	if i != nil {
		return i.next
	}
	return nil
}

二.LinkTable定义

LinkTable及一些方法

package menu

import (
	"errors"
)

type LinkTable struct {
	head *LinkNode
	tail *LinkNode
	len  int
}

const MAX_CMD = 20

//添加结点
func (i *LinkTable) Add(cmd *LinkNode) error {
	//结点若存在
	res := i.Find(cmd.command)
	if res != nil {
		return errors.New("command exist")
	}
	//列表达上限
	if i.len >= MAX_CMD {
		return errors.New("table full")
	}
	//边界条件
	if i.head == nil {
		i.head = cmd
		i.tail = cmd
		i.len = 1
		return nil
	}
	//插入结点
	i.len++
	i.tail.next = cmd
	i.tail = i.tail.next
	return nil
}

//查找结点
func (i *LinkTable) Find(cmd string) *LinkNode {
	for n := i.head; n != nil; n = n.next {
		if n.command == cmd {
			return n
		}
	}
	return nil
}

//删除结点
func (i *LinkTable) Delete(cmd string) error {
	//空列表
	if i.head == nil {
		return errors.New("table empty")
	}
	//若为头节点
	if i.head.command == cmd {
		i.head = i.head.next
		//删除后列表为空
		if i.head == nil {
			i.tail = i.head
		}
		return nil
	}
	//删除结点
	pre := i.head
	for n := pre.next; n != nil; {
		if n.command == cmd {
			pre.next = n.next
			if i.tail == n {
				i.tail = pre
			}
			return nil
		}
		pre = n
		n = n.next
	}
	return errors.New("not exist")
}

//执行命令
func (i *LinkTable) Exec(command string) error {
	res := i.Find(command)
	if res == nil {
		println("Invalid command! Use help for more information!\n")
		return nil
	}
	res.cmdDo.do()
	return nil
}

//获取头节点
func (i *LinkTable) GetHead() *LinkNode {
	if i.head == nil {
		return nil
	}
	return i.head
}

//释放列表 go会自动清理内存
func (i *LinkTable) Destroy() {
	i.head = nil
	i.tail = nil
	i.len = 0
	println("Table Destroyed!")
	return
}

//新建列表
func InitTable() *LinkTable {
	table := &LinkTable{
		head: nil,
		tail: nil,
		len:  0,
	}
	return table
}

三.指令操作实现

package menu

import (
	"fmt"
	"os"
)

type Help struct{}

func (i Help) do() {
	fmt.Printf("The commands are:\n help: advice\n version: menu version\n hello: say hello world!\n quit: leave\n")
}

type Version struct{}

func (i Version) do() {
	fmt.Printf("menu version 2.0\n")
}

type Hello struct{}

func (i Hello) do() {
	fmt.Printf("hello world!\n")
}

type Quit struct{}

func (i Quit) do() {
	os.Exit(1)
}

四.menu程序及运行结果

在之前简易版menu程序的基础上实现了LinkTable并使用接口实现指令的操作,实现多态。

package main

import (
	"fmt"
	"homework/lab1/menu"
)

func main() {
	table := menu.InitTable()
	cmd1 := menu.Create("help", new(menu.Help))
	cmd2 := menu.Create("version", new(menu.Version))
	cmd3 := menu.Create("hello", new(menu.Hello))
	cmd4 := menu.Create("quit", new(menu.Quit))
	table.Add(cmd1)
	table.Add(cmd2)
	table.Add(cmd3)
	table.Add(cmd4)
	fmt.Println("Please input your command, 'help' for advice:")

	for {
		var command string
		fmt.Scan(&command)
		table.Exec(command)
	}
}

项目地址: lanxxxxxx/menu: software engineering homework (github.com)

253

...全文
143 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧