高软 go语言 lab5
来源:互联网 发布:人类永生不死知乎 编辑:程序博客网 时间:2024/06/08 04:17
利用callback函数参数使Linktable的查询接口更加通用
C语言版本:
https://www.shiyanlou.com/courses/reports/1276044
go语言版本
知识点:
- go语言的unsafe.Pointer类型指针(对应C语言的void指针,go里面没有void指针)
用法:
void *args //C语言声明void型指针argsargs unsafe.Pointer //go语言声明unsafe.Pointer型指针args //这是个特殊指针类型,不用加*args *int //go语言声明int型指针,注意与上面的区别
- go语言的callback用法
下面将c和go的函数片段拿出来作对比
c语言:SearchLinkTableNode函数,用到了callback机制(Condition作为callback函数)
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void *args), void *args){ if(pLinkTable == NULL || Conditon == NULL) { return NULL; } tLinkTableNode * pNode = pLinkTable->pHead; while(pNode != NULL) { if(Conditon(pNode, args) == SUCCESS) { return pNode; } pNode = pNode->pNext; } return NULL;}
go语言:SearchLinkTableNode(注意callback函数Condition的特殊声明方法)
func SearchLinkTableNode(pLinkTable *LinkTable, Condition func(pNode *LinkTableNode, args unsafe.Pointer) int, args unsafe.Pointer) *LinkTableNode { if pLinkTable == nil || Condition == nil { return nil } var pNode *LinkTableNode = pLinkTable.pHead for pNode != nil { if Condition(pNode, args) == SUCCESS { return pNode } pNode = pNode.pNext } return nil}
C语言:FindCmd
tDataNode* FindCmd(tLinkTable * head, char * cmd){ return (tDataNode*)SearchLinkTableNode(head,SearchCondition, (void*) cmd);}
Go语言:FindCmd
func findCmd(head *LinkTable, cmd *string) *DataNode { return (*DataNode)(unsafe.Pointer(SearchLinkTableNode(head, SearchCondition, unsafe.Pointer(cmd))))}
附录:完整代码
linktable.go:
// linktablepackage mainimport ( "fmt" "sync" "unsafe")const SUCCESS = 0const FAILURE = -1type LinkTableNode struct { pNext *LinkTableNode}type LinkTable struct { pHead *LinkTableNode pTail *LinkTableNode SumOfNode int mutex sync.Mutex}func CreateLinkTable() *LinkTable { var pLinkTable *LinkTable = new(LinkTable) if pLinkTable == nil { return nil } pLinkTable.pHead = nil pLinkTable.pTail = nil pLinkTable.SumOfNode = 0 return pLinkTable}func DeleteLinkTable(pLinkTable *LinkTable) int { if pLinkTable == nil { return FAILURE } for pLinkTable.pHead != nil { var p *LinkTableNode = pLinkTable.pHead pLinkTable.mutex.Lock() pLinkTable.pHead = p.pNext pLinkTable.SumOfNode-- pLinkTable.mutex.Unlock() } pLinkTable.pHead = nil pLinkTable.pTail = nil pLinkTable.SumOfNode = 0 return SUCCESS}func AddLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) int { if pLinkTable == nil || pNode == nil { return FAILURE } pLinkTable.mutex.Lock() if pLinkTable.pHead == nil && pLinkTable.pTail == nil { pLinkTable.pHead = pNode pLinkTable.pTail = pNode pLinkTable.pTail.pNext = nil pLinkTable.SumOfNode = 1 } else { pLinkTable.pTail.pNext = pNode pLinkTable.pTail = pNode pLinkTable.pTail.pNext = nil pLinkTable.SumOfNode++ } pLinkTable.mutex.Unlock() return SUCCESS}func DelLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) int { if pLinkTable == nil || pNode == nil { return FAILURE } pLinkTable.mutex.Lock() var pWork *LinkTableNode = pLinkTable.pHead var pre *LinkTableNode = pWork if pLinkTable.pHead == pNode { pLinkTable.pHead = pWork.pNext pLinkTable.SumOfNode-- return SUCCESS } for pWork != nil { if pWork == pNode { pre.pNext = pWork.pNext pLinkTable.SumOfNode-- return SUCCESS } pre = pWork pWork = pWork.pNext } return FAILURE}func SearchLinkTableNode(pLinkTable *LinkTable, Condition func(pNode *LinkTableNode, args unsafe.Pointer) int, args unsafe.Pointer) *LinkTableNode { if pLinkTable == nil || Condition == nil { return nil } var pNode *LinkTableNode = pLinkTable.pHead for pNode != nil { if Condition(pNode, args) == SUCCESS { return pNode } pNode = pNode.pNext } return nil}func getLinkTableHead(pLinkTable *LinkTable) *LinkTableNode { if pLinkTable == nil { fmt.Println("LinkTable is empty") return nil } return pLinkTable.pHead}func getNextLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) *LinkTableNode { if pLinkTable == nil || pNode == nil { fmt.Println("Linktable is empty") return nil } var pWork *LinkTableNode = pLinkTable.pHead for pWork != nil { if pWork == pNode { return pWork.pNext } pWork = pWork.pNext } return nil}
menuV2.8.go
// menu_v2.8package mainimport ( "fmt" "math" "os" "strings" "time" "unsafe")type DataNode struct { next *DataNode cmd string desc string handler func()}var head *LinkTable = nilfunc SearchCondition(pLinkTableNode *LinkTableNode, args unsafe.Pointer) int { var cmd *string = (*string)(unsafe.Pointer(args)) var pNode *DataNode = (*DataNode)(unsafe.Pointer(pLinkTableNode)) if strings.Compare(pNode.cmd, *cmd) == 0 { return SUCCESS } return FAILURE}func findCmd(head *LinkTable, cmd *string) *DataNode { return (*DataNode)(unsafe.Pointer(SearchLinkTableNode(head, SearchCondition, unsafe.Pointer(cmd))))}func ShowAllCmd(head *LinkTable) int { var pNode *DataNode = (*DataNode)(unsafe.Pointer(getLinkTableHead(head))) for pNode != nil { fmt.Println(pNode.cmd, "----", pNode.desc) pNode = (*DataNode)(unsafe.Pointer(getNextLinkTableNode(head, (*LinkTableNode)(unsafe.Pointer(pNode))))) } return SUCCESS}func help() { ShowAllCmd(head)}func add() { var a, b, c int fmt.Println("Please input two integer numbers:") fmt.Scanln(&a, &b) c = a + b fmt.Printf("The result of add cmd is:\n") fmt.Printf("%d + %d = %d\n", a, b, c)}func sub() { var a, b, c int fmt.Println("Please input two integer numbers:") fmt.Scanln(&a, &b) c = a - b fmt.Printf("The result of sub cmd is:\n") fmt.Printf("%d - %d = %d\n", a, b, c)}func mul() { var a, b, c int fmt.Println("Please input two integer numbers:") fmt.Scanln(&a, &b) c = a * b fmt.Printf("The result of mul cmd is:\n") fmt.Printf("%d * %d = %d\n", a, b, c)}func div() { var a, b, c int fmt.Println("Please input two integer numbers:") fmt.Scanln(&a, &b) c = a / b fmt.Printf("The result of div cmd is:\n") fmt.Printf("%d / %d = %d\n", a, b, c)}func pow() { var a, b, c float64 fmt.Println("Please input two float64 numbers:") fmt.Scanln(&a, &b) c = math.Pow(a, b) fmt.Printf("The result of pow cmd is:\n") fmt.Printf("%.6f ^ %.6f = %.6f\n", a, b, c)}func sqrt() { var a, c float64 fmt.Println("Please input a float64 numbers:") fmt.Scanln(&a) c = math.Sqrt(a) fmt.Printf("The result of sqrt cmd is:\n") fmt.Printf("sqrt(%.6f) = %.6f\n", a, c)}func showTime() { fmt.Println(time.Now().Format("2006-01-02 15:04:05"))}func quit() { os.Exit(0)}func InitMenuData(ppLinkTable **LinkTable) int { *ppLinkTable = CreateLinkTable() var pNode *DataNode pNode = new(DataNode) pNode.cmd = "version" pNode.desc = "menu program v2.5" pNode.handler = nil AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "help" pNode.desc = "this is help cmd!" pNode.handler = help AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "add" pNode.desc = "this is add cmd!" pNode.handler = add AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "sub" pNode.desc = "this is sub cmd!" pNode.handler = sub AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "mul" pNode.desc = "this is mul cmd!" pNode.handler = mul AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "div" pNode.desc = "this is div cmd!" pNode.handler = div AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "pow" pNode.desc = "this is pow cmd!" pNode.handler = pow AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "sqrt" pNode.desc = "this is sqrt cmd!" pNode.handler = sqrt AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "time" pNode.desc = "this is showtime cmd!" pNode.handler = showTime AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) pNode = new(DataNode) pNode.cmd = "quit" pNode.desc = "this is quit cmd!" pNode.handler = quit AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode))) return SUCCESS}func main() { fmt.Println("Hello World!") InitMenuData(&head) var cmd string var Pcmd *string fmt.Println("Welcome!Use 'help' to get how to use this system.") for true { fmt.Println("input a cmd >") fmt.Scanln(&cmd) Pcmd = &cmd var p *DataNode = findCmd(head, Pcmd) if p == nil { fmt.Println("Wrong cmd!Use 'help' to get Menu List.") continue } fmt.Println(p.cmd, " ---- ", p.desc) if p.handler != nil { p.handler() } }}
阅读全文
0 0
- 高软 go语言 lab5
- 高软 go语言 lab3
- 高软 go语言 lab4
- notepad++支持go语言高亮与go语言插件
- Notepad++配置Go语言语法高亮
- GO语言高并发学习心得体会
- 【go语言爬虫】go语言高性能抓取手机号码归属地、所属运营商
- 如何用Go语言打造一个高性能MySQL Proxy
- go语言环境搭建及vim高亮设置
- kingshard: Go语言开发的高性能MySQL Proxy
- GO语言构建高并发分布式系统实践
- Go 语言构建高并发分布式系统实践
- Go Web编程(Go语言性能好、语法简单、开发效率高!)
- 【Go】Go语言初学
- Go语言
- Go语言
- Go语言
- go语言
- React Native项目实战之搭建美团个人中心界面
- STL MAP详解
- 微软面试100题-栈的push-pop序列问题
- 机器学习资料汇总
- (牛客网)变态跳台阶
- 高软 go语言 lab5
- html 之间如何通过URL传输参数,并解决中文乱码问题
- Python之IO-文件的操作
- Ubuntu 扩大虚拟机系统磁盘空间
- Codeforces 526E. Transmitting Levels (贪心)
- 行式与列式数据库
- 程序员面试金典——二进制小数_(位运算)
- USACO-Section1.2 Dual Palindromes【暴力枚举】【查找】
- I.MX6QP SD/eMMC启动