作者:ShadowYD
關鍵字參數
眾所周知很多語言的function 中都支持 key=word 關鍵字參數, 但 golang 是不支持的, 我們可以利用泛型去簡單的實現.
?
func?DefaultKeyWordParams[D?any](defVal?D,?params?...D)?D?{ ??????if?len(params)?==?0?{ ??????????????return?defVal ??????} ??????return?params[0] } func?test(category?...string)?{ ??//?不填寫則返回默認值 ??realCategory?:=?DefaultKeyWordParams[string]("AGroup",?category...) ??fmt.Println(realCategory) } func?main?()?{ ???test() }
?
快速排序
UpdateAt: 2023-02-22
實現一個可進行控制反轉的通用類型快速排序, 解決一下原生的sort包進行類型定義的繁瑣.
?
//?QuickSort?通用快速排序 func?QuickSort[T?any](arr?[]T,?compareFn?func(a,?b?T)?bool)?{ ??????if?len(arr)?2?{ ??????????????return ??????} ??????pivot?:=?arr[0] ??????left?:=?1 ??????right?:=?len(arr)?-?1 ??????for?left?<=?right?{ ??????????????if?compareFn(arr[left],?pivot)?{ ??????????????????????left++ ??????????????}?else?if?compareFn(pivot,?arr[right])?{ ??????????????????????right-- ??????????????}?else?{ ??????????????????????arr[left],?arr[right]?=?arr[right],?arr[left] ??????????????} ??????} ??????arr[0],?arr[right]?=?arr[right],?arr[0] ??????QuickSort(arr[:right],?compareFn) ??????QuickSort(arr[right+1:],?compareFn) }
?
測試用例
?
func?TestQuickSort(t?*testing.T)?{ ??????nums?:=?[]int{9,?3,?1,?7,?4,?8,?6,?2,?5} ??????fmt.Println("Unsorted:",?nums) ??????QuickSort[int](nums,?func(a,?b?int)?bool?{ ??????????????return?a??
去重復
這是一個簡單的實現, 復雜點可以通過回調 + 泛型來實現;
?
func?RemoveDuplicate[T?string?|?int?|?float64](duplicateSlice?[]T)?[]T?{ ??????set?:=?map[T]interface{}{} ??????res?:=?[]T{} ??????for?_,?item?:=?range?duplicateSlice?{ ??????????????_,?ok?:=?set[item] ??????????????if?!ok?{ ??????????????????????res?=?append(res,?item) ??????????????????????set[item]?=?nil ??????????????} ??????} ??????return?res } func?main()?{ ??????fmt.Println(RemoveDuplicate[string]([]string{"a",?"c",?"a"})) ??????fmt.Println(RemoveDuplicate[int]([]int{1,?2,?1,?1,?1})) }?
通過控制反轉實現通用的去重復方法, 支持任意類型;
?
type?Student?struct?{ ??????Name?string ??????Age??int } func?NewStudent(name?string,?age?int)?*Student?{ ??????return?&Student{Name:?name,?Age:?age} } func?DefaultFilter(item?interface{})?(uniqueKey?interface{})?{ ??????return?item.(*Student).Name } func?RemoveDuplicateWithFilter[T?comparable](compareSlice?[]T,?filterFunc?func(item?interface{})?(key?interface{}))?[]T?{ ??????set?:=?map[interface{}]interface{}{} ??????res?:=?[]T{} ??????for?_,?item?:=?range?compareSlice?{ ??????????????i?:=?filterFunc(item) ??????????????_,?ok?:=?set[i] ??????????????if?!ok?{ ??????????????????????res?=?append(res,?item) ??????????????????????set[i]?=?nil ??????????????} ??????} ??????return?res } func?main()?{ ??????s?:=?[]*Student{ ??????????????NewStudent("a",?1), ??????????????NewStudent("a",?1), ??????????????NewStudent("b",?2), ??????????????NewStudent("b",?2), ??????} ??????l?:=?RemoveDuplicateWithFilter[*Student](s,?DefaultFilter) ??????for?_,?i?:=?range?l?{ ??????????????fmt.Println(i.Name,?i.Age) ??????} }?
聯合約束類型
該例子只是一個演示, 沒有實際效果
type?ID?interface?{ ??int?|?string } //?寫法??[T?ID,?D?string]?==?[T?int?|?string,?D?string] type?UserModel[T?ID,?D?string]?struct?{ ??????Id???T ??????Name?D } func?NewUserModel[A?ID,?D?string](id?A,?name?D)?*UserModel[A,?D]?{ ??????return?&UserModel[A,?D]{Id:?id,?Name:?name} } func?main()?{ ??????fmt.Println(NewUserModel[int,?string](10,?"hello")) ??????fmt.Println(NewUserModel[string,?string]("10",?"hello")) }?
分頁
這是一段線上在使用的分頁代碼, 當無法使用外部存儲器進行分頁時直接使用該對象進行分頁, 支持任意類型;
type?KeepItem?bool //?若需要保留的item?則返回true?即可 type?FilterFunc?func(item?interface{})?KeepItem type?PageList[T?any]?struct?{ ??????Total?int?`json:"total"` ??????Page??int?`json:"page"` ??????Size??int?`json:"size"` ??????List??[]T?`json:"list"` } type?Pager[T?any]?struct?{ ??????limit???int ??????offset??int ??????total???int ??????pageCnt?int ??????list????[]T } func?NewPager[T?any](list?[]T)?*Pager[T]?{ ??????return?&Pager[T]{ ??????????????limit:??10, ??????????????offset:?1, ??????????????total:??len(list), ??????????????list:???list, ??????} } func?(this?*Pager[T])?Filter(filterFn?FilterFunc)?*Pager[T]?{ ??????tmpList?:=?[]T{} ??????for?_,?item?:=?range?this.list?{ ??????????????if?filterFn(&item)?{ ??????????????????????tmpList?=?append(tmpList,?item) ??????????????} ??????} ??????this.list?=?tmpList ??????this.total?=?len(tmpList) ??????return?this } func?(this?*Pager[T])?Offset(c?int)?*Pager[T]?{ ??????this.offset?=?c ??????return?this } func?(this?*Pager[T])?Limit(c?int)?*Pager[T]?{ ??????this.limit?=?c ??????return?this } func?(this?*Pager[T])?List()?[]T?{ ??????//?頁碼 ??????if?this.offset?<=?0?{ ??????????????this.offset?=?1 ??????} ??????//?size ??????if?this.limit?>?this.total?{ ??????????????this.limit?=?this.total ??????} ??????//?總頁數 ??????this.pageCnt?=?int(math.Ceil(float64(this.total)?/?float64(this.limit))) ??????if?this.offset?>?this.pageCnt?{ ??????????????return?[]T{} ??????} ??????startIdx?:=?(this.offset?-?1)?*?this.limit ??????endIdx?:=?startIdx?+?this.limit ??????if?endIdx?>?this.total?{ ??????????????endIdx?=?this.total ??????} ??????return?this.list[startIdx:endIdx] } func?(this?*Pager[T])?Output()?*PageList[T]?{ ??????return?&PageList[T]{ ??????????????Total:?this.total, ??????????????Page:??this.offset, ??????????????Size:??this.limit, ??????????????List:??this.list, ??????} } //?test func?main?()?{ ??page?:=?NewPager[int]([]int{1,?2,?3,?4,?5,?6,?7,?8,?9,?10}) ??????list?:=?page.Offset(1).Limit(3).Filter(func(item?interface{})?KeepItem?{ ??if?*item.(*int)%2?==?1?{ ???return?true ??} ??return?false ??????}).List() ??????fmt.Println(list) }?
通用初始化模型
可以解決在多態下使用同一個初始化函數進行對象初始化, 寫法上有點繞大家自行多實驗幾次就能明白.
type?ModelObj?interface?{ ??????User?|?Product } type?User?struct?{ ??????Uid?int } func?(this?*User)?SetId(id?int)?{ ??????this.Uid?=?id } type?Product?struct?{ ??????Pid?int } func?(this?*Product)?SetId(id?int)?{ ??????this.Pid?=?id } //?TrimModelObj?是一個動態類型的?Interface,?由M決定當前Interface的最終類型 type?TrimModelObj[M?ModelObj]?interface?{ ??????*M ??????SetId(id?int) } //?TrimModelObj[Model]?由第二個參數決定當前的動態類型; //?NewModelObj[*User,?User](32)?如?Model?是?User?類型,?最終?TrimModelObj?==?*User,所以我們需要為?Trim?傳遞?*User func?NewModelObj[Trim?TrimModelObj[Model],?Model?ModelObj](id?int)?Trim?{ ??????m?:=?new(Model) ??????t?:=?Trim(m) ??????fmt.Printf("%p? ",?m) ??????//?類型轉換成指定的*Model ??????t.SetId(id) ??????return?t } func?main()?{ ??????//?new?user?model?object ??????user?:=?NewModelObj[*User,?User](32) ??????fmt.Printf("%p? ",?user) ??????fmt.Printf("%T? ",?user) ??????fmt.Println(user.Uid) ??????//?new?product?model?object ??????prod?:=?NewModelObj[*Product,?Product](18) ??????fmt.Printf("%p? ",?prod) ??????fmt.Printf("%T? ",?prod) ??????fmt.Println(prod.Pid) }?
審核編輯:湯梓紅?
評論
查看更多