571
社区成员
发帖
与我相关
我的任务
分享指令结点及其接口和方法
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及一些方法
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程序的基础上实现了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