collection v1.3.1升級全記錄
阿新 • • 發佈:2020-10-22
# collection v1.3.1升級全記錄
專案地址: https://github.com/jianfengye/collection 歡迎star。
collection 手冊地址: http://collection.funaio.cn/
collection庫升級到v1.3.1版本。
從v1.2.0 到v1.3.1 開發做了如下改動:
* 說明文件改造成線上手冊
* 增加了 ObjPointCollection 結構
* 增加了 toObjs 方法
* 重構了 AbsArray
* 增加了 ContainsCount 方法
* errors 庫換成 github.com/pkg/errors 庫
# 說明文件改造成線上手冊
這個是組內前端同學的啟發,他們寫文件手冊喜歡用vuepress。於是我將之前的庫說明手冊,一個大檔案 README.md,修改成為了 docs 目錄下的“指南” 和 “手冊” 兩個部分。手冊中每個方法都是一個 markdown。
我的思考是這樣把方法的說明拆分開,後續手冊中可以擴充套件一些使用示例等。使用 vuepress 的好處還是不少的,一個是在自己的阿里雲伺服器上搭建了一個手冊地址:http://collection.funaio.cn/ 。 這個地址讓我在開發過程中更方便查看了,不用再上 github 上面看了。畢竟 github 最近也不是那麼好登陸了。
![20201022131102](http://tuchuang.funaio.cn/md/20201022131102.png)
這裡可以安利下 vuepress,很好用的一個 markdown 轉 html 的工具。
# 增加了 ObjPointCollection 結構
這個需求源自我業務開發中遇到的需求。指標物件陣列。我們希望指標物件陣列也能使用 Colleciton 庫的所有方法。所以增加了這個方法。
```golang
type FooBar struct {
Foo string
Bar int
}
func FooBarCompare(a interface{}, b interface{}) int {
aobj := a.(*FooBar)
bobj := b.(*FooBar)
return aobj.Bar - bobj.Bar
}
func InitFooObjPoints() []*FooBar {
return []*FooBar{
{
Foo: "astring",
Bar: 1,
},
{
Foo: "bstring",
Bar: 2,
},
}
}
func TestObjPointCollection_Normal(t *testing.T) {
objs := InitFooObjPoints()
coll := NewObjPointCollection(objs).SetCompare(FooBarCompare)
// [Append](#Append) 掛載一個元素到當前Collection
{
count := coll.Copy().Append(&FooBar{
Foo: "cstring",
Bar: 3,
}).Count()
if count != 3 {
t.Fatal("append error")
}
}
// [Contain](#Contain) 判斷一個元素是否在Collection中
{
obj := objs[0]
if coll.Contains(obj) != true {
t.Fatal("contains error")
}
}
// [Copy](#Copy) 根據當前的陣列,創造出一個同類型的陣列
{
if coll.Copy().Count() != 2 {
t.Fatal("copy error")
}
}
}
```
# 增加了 toObjs 方法
這個方法是針對 ObjCollection 和 ObjPointCollection 設計的。 如果我們想要將 Collection 還原成物件陣列,或者物件指標陣列的時候,可以使用這個方法。這個方法使用了反射。
```golang
func TestObjPointCollection_ToObjs(t *testing.T) {
a1 := &Foo{A: "a1", B: 1}
a2 := &Foo{A: "a2", B: 2}
a3 := &Foo{A: "a3", B: 3}
bArr := []*Foo{}
objColl := NewObjPointCollection([]*Foo{a1, a2, a3})
err := objColl.ToObjs(&bArr)
if err != nil {
t.Fatal(err)
}
if len(bArr) != 3 {
t.Fatal("toObjs error len")
}
if bArr[1].A != "a2" {
t.Fatal("toObjs error copy")
}
}
```
# 重構了 AbsArray
之前的這篇 http://collection.funaio.cn/guide/introduce.html 說了我當時設計 collection 庫的思考。但是在1.3.1 版本的時候,覺得實現的思維還是不夠清晰。這次我的改造包括在底層 AbsArray 中儲存了上層 collection 的型別。
```
const (
TYPE_UNKNWON EleType = iota
Type_INT
Type_INT64
Type_INT32
TYPE_STRING
TYPE_FLOAT32
TYPE_FLOAT64
TYPE_OBJ
TYPE_OBJ_POINT
)
```
然後在內部實現了 must 相關的防禦方法:
```
mustSetCompare
mustBeNumType
mustBeBaseType
mustNotBeBaseType
mustNotBeEmpty
```
最後在每個具體實現的方法前先進行防禦判斷。這樣整體程式碼可讀性會得到提升。
# 增加 ContainsCount 方法
這個方法也是使用過程中提到的,我們希望不僅僅判斷一個元素是否在陣列中,也想判斷這個元素在陣列中出現了幾次。於是便有了這個方法。
```golang
func TestAbsCollection_ContainsCount(t *testing.T) {
intColl := NewIntCollection([]int{1, 2, 2, 3})
count := intColl.ContainsCount(2)
if count != 2 {
t.Fatal(errors.New("contains count error"))
}
}
```
# errors 換成 github.com/pkg/errors
官方 errors 庫換成 pkg/errors 庫的好處這裡就不贅述了,有興趣的可以參考 https://www.bilibili.com/video/BV1hE411c7Ze/
# 總結
最近內部又有一個新的模組服務使用 collection 庫進行業務開發,真實感受加快了不少開發速度。
祝用的