page contents

Golang开源容器库gocontainer介绍

与Java比起来,golang是一门新兴的编程语言。Java经过26年的发展,生态已经非常完善。JDK也已经实现了各种丰富的容器供开发者使用。而golang除了语言自带的array、slice和map等数据结构之外,...

attachments-2021-07-2ML4UdN060e7bccec3360.png

与Java比起来,golang是一门新兴的编程语言。Java经过26年的发展,生态已经非常完善。JDK也已经实现了各种丰富的容器供开发者使用。而golang除了语言自带的array、slice和map等数据结构之外,几乎没有实现任何其它的容器。

gocontainer借鉴了JDK的一些实现,并结合golang做了一定的创新。这个项目在github上开源,地址如下:


gocontainer概要介绍

gocontainer主要是参考JDK并结合golang自身的特点,为golang实现的一套容器库。gocontainer不依赖任何第三方软件包;套用HAProxy的宣传词"zero-copy",gocontainer是"zero-dependency"。

gocontainer不是线程安全的。这么设计出于几个原因:1、在不需要线程(goroutine)安全的环境中使用,性能更好;2、即使在需要线程(goroutine)安全的环境中使用,应用层也可以很容易的实现加锁同步;3、开始阶段,尽可能的简化gocontainer的设计与实现。后续的改进尽可能的基于社区的反馈来进行,而不是零君个人的各种猜想。

gocontainer v0.0.1版本实现了stack、queue、set、list(包含ArrayList和LinkedList)、priorityQueue以及linkedMap这几种容器。下面会对这几种容器分别做简要的介绍。更详细的介绍以及示例,请直接访问github上的开源项目:


如何使用gocontainer

使用gocontainer极其容易,如果你需要使用某个容器,只需要在代码中import相应的包,然后直接使用即可。下面是一个完整的使用arrayList的例子,

package main
import (
  "fmt"
  "github.com/ahrtr/gocontainer/list"
)
func main() {
  al := list.NewArrayList()
  al.Add(5) al.Add(6)
  al.Add(7)
  // Iterate all the elements
  fmt.Println("Iterate (method 1): ") 
  for i := 0; i < al.Len(); i++ {
     v, _ := al.Get(i)
     fmt.Printf(" Index: %d, value: %v\n", i, v)
  }
}


公共接口(Common Interface)

每一个容器都有一个对应的接口定义,对于上层开发者来说,只需要关心接口中定义的方法即可。因为所有的容器都包含一些签名完全相同的方法,所以就定义了一个公共的接口,如下:

// Interface is a type of collection, all containers should implement this interface.
type Interface interface {
// IsEmpty returns true if this container contains no elements.
IsEmpty() bool
// Clear removes all of the elements from this container.
Clear()
// Len is the number of elements in the container.
// Len() is also included in sort.Interface. Only golang 1.14 supports embedding of Interfaces with overlapping method sets,
// so let's add it in this interface in the future.
//Len() int
}

这里值得一提的是,零君原本想把方法Len()也加入这个公共接口,但由于有些容器实现了sort.Interface,而该接口中也包含方法Len()。这样同时实现了这个两个接口的“类”,就会包含重复的方法Len()。这种钻石型的“继承”结构,只有golang 1.14才支持,对于老版本的golang版本,编译时就会报错。由于目前很多开发者还是使用老版本的golang,所以零君暂时就没有将Len()加入该公共接口。


几种常用容器简洁

gocontainer中实现的几种常用容器的简介包含在下面的表格中:

容器名
介绍
stack
是一种后进先出的容器
queue
是一种先进先出的容器,典型的应用场景是消费者-生产者模型。
set
特点是容器内不允许包含重复的值。所以包含在容器中的值必须是可以用==比较的;更具体的来说,可以作为key存储在map中的类型,都可以存储在set中。
list
包含arrayList和linkedList两种类型。
priorityQueue
基于堆排序的一种队列。队列头的元素始终是优先级最高的元素。优先级的高低由数据的自然顺序(默认队列头是最小值),或者由上层应用提供的comparator来决定。
linkedMap
基于map和一个双向链表实现。map可以保证查询的速度,而双向链表保证了确定的遍历顺序。

这几种容器中,只有set、list和linkedMap支持遍历,其中list和linkedMap支持正向遍历和反向遍历。还是以list为例来说明,正向遍历除了使用上面例子中所示的for循环(i从0到size-1)的方法,还可以使用下面的方法:

// To iterate over a list (where l is an instance of list.Interface):
it, hasNext := l.Iterator()
var v interface{}
for hasNext {
v, hasNext = it()
// do something with v
}

同理,反向遍历list,除了使用for循环(i从size-1到0),还可以使用下面的方法:

// To iterate over a list in reverse order (where l is an instance of list.Interface):
it, hasPrev := l.ReverseIterator()
var v interface{}
for hasPrev {
v, hasPrev = it()
// do something with v
}


关于排序

因为list直接实现了接口sort.Interface,所以无论是arrayList还是linkedList,都可以直接使用golang自带的sort.Sort(data)进行排序。对于golang一些内置的数据类型(例如bool、数字、字符串等)默认是按照升序排列,如果想采取倒序,则使用:

sort.Sort(sort.Reverse(data))

对于list(包括arrayList和linkedList)和priorityQueue,都可以利用WithComparator方法传入一个Comparator。这样上层应用可以完全定制排序机制。

WithComparator(c gsort.Comparator) Interface


接口Comparator定义如下:

// Comparator imposes a total ordering on some collection of objects.
// Comparators can be passed to the construction function of a container(such as ArrayList, LinkedList or PriorityQueue) to allow precise control over the sort order.
type Comparator interface {
// Compare compares its two arguments for order.// It returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
Compare(v1 interface{}, v2 interface{}) (int, error)
}

这里就不举例说明了,具体请查看gocontainer在github上的说明与示例。

总结

本文简要介绍了开源项目gocontainer,以及其为golang实现几种常用的容器。目前该项目仍在不断的开发与完善之中,欢迎任何人提出任何建议,或者参与到该开源项目中。

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

程序员编程交流QQ群:805358732

如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。

attachments-2022-06-79zXno9862ad3438e1d90.jpeg

  • 发表于 2021-07-09 11:05
  • 阅读 ( 822 )
  • 分类:Golang

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1474 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章