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

這裡可以安利下 vuepress,很好用的一個 markdown 轉 html 的工具。

增加了 ObjPointCollection 結構

這個需求源自我業務開發中遇到的需求。指標物件陣列。我們希望指標物件陣列也能使用 Colleciton 庫的所有方法。所以增加了這個方法。



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 還原成物件陣列,或者物件指標陣列的時候,可以使用這個方法。這個方法使用了反射。


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 方法

這個方法也是使用過程中提到的,我們希望不僅僅判斷一個元素是否在陣列中,也想判斷這個元素在陣列中出現了幾次。於是便有了這個方法。

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 庫進行業務開發,真實感受加快了不少開發速度。

祝用的高興。

相關文章