使用Go写一个LinkTable

EvergIow 2022-04-07 04:10:50

目录

  • 代码仓库
  • 心得体会
  • 接口定义
  • 接口实现
  • 测试代码
  • 测试结果
  • 作者:551

代码仓库

linktable · qyanzh/menu - 码云 - 开源中国 (gitee.com)

心得体会

先写接口,把接口调用串起来,然后再实现,可以使得代码结构变得更加清晰,让我们对代码流程有一个宏观的把握,并且可以提早发现错误,提高代码质量。

接口定义

type Node struct {
    Next *Node
}

type ILinkTable interface {
    AddLinkTableNode(node *Node) error
    DelLinkTableNode(node *Node) error
    GetLinkTableHead() *Node
    GetNextLinkTableNode(node *Node) (*Node, error)
}

接口实现

type LinkTable struct {
    Head      *Node
    Tail      *Node
    SumOfNode int
    mutex     sync.Mutex
}

func (lt *LinkTable) AddLinkTableNode(node *Node) error {
    if node == nil {
        return fmt.Errorf("nil node")
    }
    lt.mutex.Lock()
    if lt.Head == nil {
        lt.Head = node
        lt.Tail = node
    } else {
        lt.Tail.Next = node
        lt.Tail = lt.Tail.Next
    }
    lt.SumOfNode++
    lt.mutex.Unlock()
    return nil
}

func (lt *LinkTable) DelLinkTableNode(node *Node) error {
    if node == nil {
        return fmt.Errorf("nil node")
    }
    if lt.Head == nil {
        return fmt.Errorf("empty table")
    }
    pre := &Node{Next: lt.Head}
    for pre.Next != nil {
        if pre.Next == node {
            lt.mutex.Lock()
            pre.Next = node.Next
            if node == lt.Head {
                lt.Head = lt.Head.Next
            }
            if node == lt.Tail {
                lt.Tail = lt.Tail.Next
            }
            lt.SumOfNode--
            lt.mutex.Unlock()
            return nil
        }
        pre = pre.Next
    }
    return fmt.Errorf("node isn't in table")
}

func (lt *LinkTable) GetLinkTableHead() *Node {
    return lt.Head
}

func (lt *LinkTable) GetNextLinkTableNode(node *Node) (*Node, error) {
    if node == nil {
        return nil, fmt.Errorf("nil node")
    }
    if lt.Head == nil {
        return nil, fmt.Errorf("empty table")
    }
    for p := lt.Head; p != nil; {
        if p == node {
            return p.Next, nil
        }
        p = p.Next
    }
    return nil, fmt.Errorf("node isn't in table")
}

func CreateLinkTable() *LinkTable {
    return &LinkTable{}
}

测试代码

type MyNode struct {
   Node
   data int
}

func TestLinkTable(t *testing.T) {
   lt := CreateLinkTable()
   for i := 0; i < 10; i++ {
      node := MyNode{data: i}
      pNode := (*Node)(unsafe.Pointer(&node))

      if err := lt.AddLinkTableNode(pNode); err != nil {
         panic(err)
      }
      fmt.Println("AddLinkTableNode")
   }
   lt.Traverse()
   myNode := lt.Search(5)
   fmt.Println(myNode.data)
   fmt.Println("DelLinkTableNode")
   err := lt.DelLinkTableNode((*Node)(unsafe.Pointer(myNode)))
   if err != nil {
      panic(err)
   }
   lt.Traverse()
}

func (lt *LinkTable) Search(target int) *MyNode {
   var err error
   node := lt.GetLinkTableHead()

   for node != nil {
      myNode := (*MyNode)(unsafe.Pointer(node))
      if myNode.data == target {
         return myNode
      }
      node, err = lt.GetNextLinkTableNode(node)
      if err != nil {
         panic(err)
      }
   }
   return nil
}

func (lt *LinkTable) Traverse() {
   var err error
   node := lt.GetLinkTableHead()

   for node != nil {
      myNode := (*MyNode)(unsafe.Pointer(node))
      fmt.Printf("%d ", myNode.data)
      node, err = lt.GetNextLinkTableNode(node)
      if err != nil {
         panic(err)
      }
   }
   fmt.Println()
}

测试结果

img

作者:551

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

566

社区成员

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

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