一. 复杂结构数据合并
复杂数据结构根据条件合并需求 结构体
type OrderInfo struct {
OrderId string `json:"orderId"`
OccupateionList [ ] Occupateion `json:"occupateionList"`
}
type Occupateion struct {
RoomNo string `json:"roomNo"`
GuestList [ ] Guest `json:"guestList"`
}
type Guest struct {
guestId string `json:"guestId"`
Name string `json:"name"`
}
最初的合并示例
func OrderMerge ( orderListNew, orderListOld [ ] OrderInfo) [ ] OrderInfo {
if len ( orderListNew) <= 0 {
return orderListOld
}
if len ( orderListOld) <= 0 {
return orderListNew
}
var oOld OrderInfo
for i, oNew := range orderListNew {
orderFla := true
for _ , oOld = range orderListOld {
if oNew. OrderId == oOld. OrderId {
orderFla = false
}
}
if orderFla {
orderListNew = append ( orderListNew, oOld)
continue
} else {
oNew. OccupateionList = OccMerge ( oNew. OccupateionList, oOld. OccupateionList)
orderListNew[ i] = oNew
}
}
return orderListNew
}
func OccMerge ( occListNew, occListOld [ ] Occupateion) [ ] Occupateion {
if len ( occListNew) <= 0 {
return occListOld
}
if len ( occListOld) <= 0 {
return occListNew
}
var occOld Occupateion
for i, occNew := range occListNew {
occFlag := true
for _ , occOld = range occListOld {
if occOld. RoomNo == occNew. RoomNo {
occFlag = false
}
}
if occFlag {
occListNew = append ( occListNew, occOld)
continue
} else {
occNew. GuestList = GuestMerge ( occNew. GuestList, occOld. GuestList)
occListNew[ i] = occNew
}
}
return occListNew
}
func GuestMerge ( guestListNew, guestListOld [ ] Guest) [ ] Guest {
if len ( guestListNew) <= 0 {
return guestListOld
}
if len ( guestListOld) <= 0 {
return guestListNew
}
for _ , gNew := range guestListNew {
gFlag := true
for _ , gOld := range guestListOld {
if gNew. guestId == gOld. guestId {
gFlag = false
}
}
if gFlag {
guestListOld = append ( guestListOld, gNew)
}
}
return guestListOld
}
使用Map优化
func OrderMerge ( orderListNew, orderListOld [ ] OrderInfo) [ ] OrderInfo {
orderMap := make ( map [ string ] * OrderInfo, len ( orderListOld) )
for i, order := range orderListOld {
orderMap[ order. OrderId] = & orderListOld[ i]
}
for _ , orderNew := range orderListNew {
if orderOld, ok := orderMap[ orderNew. OrderId] ; ok {
orderOld. OccupateionList = OccMerge ( orderNew. OccupateionList, orderOld. OccupateionList)
} else {
orderListOld = append ( orderListOld, orderNew)
orderMap[ orderNew. OrderId] = & orderListOld[ len ( orderListOld) - 1 ]
}
}
return orderListOld
}
func OccMerge ( occListNew, occListOld [ ] Occupateion) [ ] Occupateion {
occMap := make ( map [ string ] * Occupateion, len ( occListOld) )
for i, occ := range occListOld {
occMap[ occ. RoomNo] = & occListOld[ i]
}
for _ , occNew := range occListNew {
if occOld, ok := occMap[ occNew. RoomNo] ; ok {
occOld. GuestList = GuestMerge ( occNew. GuestList, occOld. GuestList)
} else {
occListOld = append ( occListOld, occNew)
occMap[ occNew. RoomNo] = & occListOld[ len ( occListOld) - 1 ]
}
}
return occListOld
}
func GuestMerge ( guestListNew, guestListOld [ ] Guest) [ ] Guest {
guestMap := make ( map [ string ] * Guest, len ( guestListOld) )
for i, guest := range guestListOld {
guestMap[ guest. guestId] = & guestListOld[ i]
}
for _ , guestNew := range guestListNew {
if _ , ok := guestMap[ guestNew. guestId] ; ! ok {
guestListOld = append ( guestListOld, guestNew)
guestMap[ guestNew. guestId] = & guestListOld[ len ( guestListOld) - 1 ]
}
}
return guestListOld
}
使用Visitor访问者设计模式优化
Visitor模式是一种将数据结构和操作解耦的设计模式,将操作封装到一个Visitor对象中,根据具体的需求选择不同的Visitor进行访问,使用Visitor设计模式优化后,代码更加清晰、简洁和可扩展。 定义OrderVisitor接口,用于访问OrderInfo对象
type OrderVisitor interface {
VisitOrder ( order * OrderInfo)
}
type OrderInfo struct {
OrderId string `json:"orderId"`
OccupationList [ ] Occupation `json:"occupationList"`
}
func ( o * OrderInfo) Accept ( visitor OrderVisitor) {
visitor. VisitOrder ( o)
}
定义OccupationVisitor接口,用于访问Occupation对象
type OccupationVisitor interface {
VisitOccupation ( occ * Occupation)
}
type Occupation struct {
RoomNo string `json:"roomNo"`
GuestList [ ] Guest `json:"guestList"`
}
func ( o * Occupation) Accept ( visitor OccupationVisitor) {
visitor. VisitOccupation ( o)
}
定义三个具体的Visitor:OrderMergeVisitor、OccMergeVisitor和GuestMergeVisitor,分别用于合并OrderInfo对象、Occupation对象和Guest对象:
type OrderMergeVisitor struct {
orderMap map [ string ] * OrderInfo
}
func ( v * OrderMergeVisitor) VisitOrder ( order * OrderInfo) {
if orderOld := v. orderMap[ order. OrderId] ; orderOld != nil {
orderOld. OccupationList = OccMerge ( order. OccupationList, orderOld. OccupationList)
} else {
v. orderMap[ order. OrderId] = order
}
}
type OccMergeVisitor struct {
occMap map [ string ] * Occupation
}
func ( v * OccMergeVisitor) VisitOccupation ( occ * Occupation) {
if occOld := v. occMap[ occ. RoomNo] ; occOld != nil {
occOld. GuestList = GuestMerge ( occ. GuestList, occOld. GuestList)
} else {
v. occMap[ occ. RoomNo] = occ
}
}
type GuestMergeVisitor struct {
guestMap map [ string ] * Guest
}
func ( v * GuestMergeVisitor) VisitGuest ( guest * Guest) {
if _ , ok := v. guestMap[ guest. GuestId] ; ! ok {
v. guestMap[ guest. GuestId] = guest
}
}
在OrderMerge函数中调用这三个Visitor
func OrderMerge ( orderListNew, orderListOld [ ] OrderInfo) [ ] OrderInfo {
orderMap := make ( map [ string ] * OrderInfo, len ( orderListOld) )
for i, order := range orderListOld {
orderMap[ order. OrderId] = & orderListOld[ i]
}
for _ , orderNew := range orderListNew {
orderNew. Accept ( & OrderMergeVisitor{ orderMap} )
}
returnMap := make ( map [ string ] * OrderInfo, len ( orderListOld) )
for _ , order := range orderMap {
order. Accept ( & OccMergeVisitor{ returnMap} )
}
var resultList [ ] OrderInfo
for _ , order := range returnMap {
order. Accept ( & GuestMergeVisitor{ returnMap} )
resultList = append ( resultList, * order)
}
return resultList
}
二. Go中的FunctionalOptions可选参数模式
Functional Options 模式的优点:
易于阅读和维护: 使用 Functional Options 模式能够使代码可读性更强,易于维护。对于一些带有很多可选参数的函数,如果不使用 Functional Options 模式,那么在调用这个函数时需要填写很多参数,而且如果忘了填写某个参数,编译器也不会给出警告或者错误,可能会导致一些问题,使用 Functional Options 模式则可以避免这种情况。 自由组合: 使用 Functional Options 模式能够让用户根据自己的需求任意组合选项参数,从而提高函数的灵活性。同样的函数,不同的选项参数可以产生不同的效果,用户可以根据自己的需求来自由组合选项参数,从而实现不同的功能。
示例1
type Option func ( [ ] * OrderInfo) [ ] * OrderInfo
func FilterOrdersByDate ( start, end time. Time) Option {
return func ( orders [ ] * OrderInfo) [ ] * OrderInfo {
filteredOrders := [ ] * OrderInfo{ }
for _ , order := range orders {
if order. Date. After ( start) && order. Date. Before ( end) {
filteredOrders = append ( filteredOrders, order)
}
}
return filteredOrders
}
}
func SortOrdersByDateDesc ( ) Option {
return func ( orders [ ] * OrderInfo) [ ] * OrderInfo {
sort. Slice ( orders, func ( i, j int ) bool {
return orders[ i] . Date. After ( orders[ j] . Date)
} )
return orders
}
}
func ProcessOrders ( orders [ ] * OrderInfo, options ... Option) [ ] * OrderInfo {
for _ , option := range options {
orders = option ( orders)
}
return orders
}
示例2
type Options struct {
title string
description string
keywords [ ] string
rewrites map [ string ] string
}
type Option func ( opt * Options)
func Title ( title string ) Option {
return func ( opt * Options) {
opt. title = title
}
}
func Description ( description string ) Option {
return func ( opt * Options) {
opt. description = description
}
}
func Keywords ( keywords [ ] string ) Option {
return func ( opt * Options) {
opt. keywords = keywords
}
}
func Rewrites ( rewrites map [ string ] string ) Option {
return func ( opt * Options) {
opt. rewrites = rewrites
}
}
type Page struct {
title string
description string
keywords [ ] string
rewrites map [ string ] string
}
func NewPage ( url string , title string , options ... Option) * Page {
opt := & Options{ }
for _ , o := range options {
o ( opt)
}
page := & Page{
title: opt. title,
description: opt. description,
keywords: opt. keywords,
rewrites: opt. rewrites,
}
return page
}
page := NewPage ( "https://www.example.com/" , "Example" , Title ( "Example Page" ) , Description ( "This is an example page." ) )
三. Go中的Pipeline模式
实现流式处理的一种常见方式,主要通过将数据处理过程分解成多个阶段,并将每个阶段封装成一个函数,然后通过将这些函数串联起来形成一个管道,从而实现流式处理
易于编写和组合: Pipeline 模式将数据处理过程划分成多个阶段,每个阶段只需要关注自己的输入和输出,这大大降低了代码的复杂度和耦合度,同时使得编写和组合阶段函数变得非常容易。 可重用性强: Pipeline 模式中的每个阶段函数都是独立的,可以在不同的 Pipeline 中重复使用,提高代码的可重用性。 可扩展性强: Pipeline 模式中的每个阶段函数都可以很容易地被替换或者新增,使得整个 Pipeline 的功能得到扩展或改进
示例
func FilterOrdersByDate ( orders [ ] * OrderInfo, start, end time. Time) [ ] * OrderInfo {
filteredOrders := [ ] * OrderInfo{ }
for _ , order := range orders {
if order. Date. After ( start) && order. Date. Before ( end) {
filteredOrders = append ( filteredOrders, order)
}
}
return filteredOrders
}
func SortOrdersByDateDesc ( orders [ ] * OrderInfo) [ ] * OrderInfo {
sort. Slice ( orders, func ( i, j int ) bool {
return orders[ i] . Date. After ( orders[ j] . Date)
} )
return orders
}
func ProcessOrders ( orders [ ] * OrderInfo, pipeline ... func ( [ ] * OrderInfo) [ ] * OrderInfo) [ ] * OrderInfo {
for _ , stage := range pipeline {
orders = stage ( orders)
}
return orders
}
示例2
type Student struct {
Name string
Scores [ ] int
}
func FilterTop10Students ( students [ ] * Student) [ ] * Student {
top10Students := make ( [ ] * Student, 0 , 10 )
for _ , s := range students {
if len ( top10Students) < 10 {
top10Students = append ( top10Students, s)
} else {
minScore := top10Students[ 0 ] . Scores[ 0 ]
minIndex := 0
for i, t := range top10Students {
if t. Scores[ 0 ] < minScore {
minScore = t. Scores[ 0 ]
minIndex = i
}
}
if s. Scores[ 0 ] > minScore {
top10Students[ minIndex] = s
}
}
}
return top10Students
}
func SortStudentsByAverageScore ( students [ ] * Student) [ ] * Student {
sort. Slice ( students, func ( i, j int ) bool {
sumI := 0
for _ , score := range students[ i] . Scores {
sumI += score
}
avgI := float64 ( sumI) / float64 ( len ( students[ i] . Scores) )
sumJ := 0
for _ , score := range students[ j] . Scores {
sumJ += score
}
avgJ := float64 ( sumJ) / float64 ( len ( students[ j] . Scores) )
return avgI > avgJ
} )
return students
}
func PrintStudents ( students [ ] * Student) {
fmt. Println ( "排名\t姓名\t平均分" )
for i, s := range students {
sum := 0
for _ , score := range s. Scores {
sum += score
}
avg := float64 ( sum) / float64 ( len ( s. Scores) )
fmt. Printf ( "%d\t%s\t%.2f\n" , i+ 1 , s. Name, avg)
}
}
func main ( ) {
students := [ ] * Student{
{ "张三" , [ ] int { 67 , 82 , 76 } } ,
{ "李四" , [ ] int { 87 , 65 , 94 } } ,
{ "王五" , [ ] int { 69 , 74 , 79 } } ,
{ "赵六" , [ ] int { 91 , 88 , 87 } } ,
{ "钱七" , [ ] int { 82 , 73 , 64 } } ,
{ "韩八" , [ ] int { 94 , 96 , 92 } } ,
}
top10Students := FilterTop10Students ( students)
sortedStudents := SortStudentsByAverageScore ( top10Students)
PrintStudents ( sortedStudents)
}
四. Go中的MapReduce模式
MapReduce 模式优点:是一种分布式计算模型,主要用于处理大规模数据集。该模型包含两个阶段:Map 阶段和 Reduce 阶段。在 Map 阶段中,数据会被分割成多个小块,并且每个小块都会被映射为一个键值对;在 Reduce 阶段中,则将所有具有相同键的值进行合并,并最终输出结果
可以处理大规模数据集,支持分布式计算。 支持数据并行处理,提高了计算效率。 相比于传统的单线程或者多线程计算模型,MapReduce 模式具有更好的容错和故障处理能力
示例
package main
import (
"fmt"
"sort"
)
func main ( ) {
text := "afs dfasgah afdgfad gasd dffsdfas"
var keyValueMaps [ ] map [ string ] int
words := splitWords ( text)
for _ , word := range words {
keyValueMap := map [ string ] int { word: 1 }
keyValueMaps = append ( keyValueMaps, keyValueMap)
}
intermediate := make ( map [ string ] [ ] int )
for _ , keyValueMap := range keyValueMaps {
for key, value := range keyValueMap {
intermediate[ key] = append ( intermediate[ key] , value)
}
}
var keys [ ] string
for k := range intermediate {
keys = append ( keys, k)
}
sort. Strings ( keys)
finalResult := make ( map [ string ] int )
for _ , key := range keys {
finalResult[ key] = reduce ( key, intermediate[ key] )
}
fmt. Println ( finalResult)
}
func reduce ( key string , values [ ] int ) int {
sum := 0
for _ , v := range values {
sum += v
}
return sum
}
func splitWords ( input string ) [ ] string {
var words [ ] string
word := ""
for i := 0 ; i < len ( input) ; i++ {
if input[ i] != ' ' {
word += string ( input[ i] )
} else {
words = append ( words, word)
word = ""
}
}
if word != "" {
words = append ( words, word)
}
return words
}
func mapToKeyValue ( words [ ] string ) map [ string ] int {
keyValueMap := make ( map [ string ] int )
for _ , word := range words {
if _ , ok := keyValueMap[ word] ; ok {
keyValueMap[ word] += 1
} else {
keyValueMap[ word] = 1
}
}
return keyValueMap
}
五. 三方库 go-linq
go-linq是一个开源的Go语言库,提供了基于LINQ风格的查询语法,支持对切片、字典、数组等数据进行查询、过滤、排序、分组等操作,并且代码简洁清晰易懂,使用方便 go-linq常用API介绍
func From ( s interface { } ) Enumerable
func ( e Enumerable) Where ( f func ( interface { } ) bool ) Enumerable
func ( e Enumerable) Select ( f func ( interface { } ) interface { } ) Enumerable
func ( e Enumerable) Join ( inner Enumerable, outerKeySelector func ( interface { } ) interface { } , innerKeySelector func ( interface { } ) interface { } , resultSelector func ( interface { } , interface { } ) interface { } ) Enumerable
func ( e Enumerable) GroupBy ( keySelector func ( interface { } ) interface { } , elementSelector func ( interface { } ) interface { } ) Enumerable
func ( e Enumerable) OrderBy ( fn func ( interface { } ) interface { } ) Enumerable
func ( e Enumerable) OrderByDescending ( fn func ( interface { } ) interface { } ) Enumerable
func ( e Enumerable) ThenBy ( fn func ( interface { } ) interface { } ) Enumerable
func ( e Enumerable) ThenByDescending ( fn func ( interface { } ) interface { } ) Enumerable
func ( e Enumerable) ToSlice ( target interface { } )
func ( e Enumerable) ToMap ( keySelector func ( interface { } ) interface { } , elementSelector func ( interface { } ) interface { } ) map [ interface { } ] interface { }
func ( e Enumerable) Sum ( ) ( sum float64 )
func ( e Enumerable) Average ( ) ( average float64 )
func ( e Enumerable) Min ( ) ( min interface { } )
func ( e Enumerable) Max ( ) ( max interface { } )
func ( e Enumerable) Count ( ) ( count int )
func ( e Enumerable) First ( ) interface { }
func ( e Enumerable) Last ( ) interface { }
func ( e Enumerable) Single ( ) interface { }
使用示例
package main
import (
"fmt"
"github.com/ahmetb/go-linq"
)
type Student struct {
Name string
Age int
}
func main ( ) {
students := [ ] Student{
{ Name: "Tom" , Age: 18 } ,
{ Name: "Mary" , Age: 21 } ,
{ Name: "Jack" , Age: 25 } ,
{ Name: "Lucy" , Age: 19 } ,
{ Name: "Bob" , Age: 22 } ,
}
result := make ( [ ] Student, 0 )
linq. From ( students) . Where ( func ( s interface { } ) bool {
return s. ( Student) . Age > 20
} ) . OrderBy ( func ( s interface { } ) interface { } {
return s. ( Student) . Name
} ) . ToSlice ( & result)
fmt. Println ( "Filtered and sorted students:" )
for _ , student := range result {
fmt. Printf ( "%s (%d)\n" , student. Name, student. Age)
}
}
六. 三方库 go-streams
go-streams是一个基于Go语言的功能强大的流处理框架,能够让用户方便地进行流式数据处理,包括数据转换、聚合、筛选过滤等操作。它提供了一系列高层次的API,使得用户可以轻松地创建和操作流数据,同时还支持分布式处理和无状态处理等功能 go-streams中常用的API如下:
streams. NewPipeline ( ... streams. Operation)
streams. NewSliceSource ( [ ] interface { } )
streams. Map ( func ( interface { } ) interface { } )
streams. Filter ( func ( interface { } ) bool )
streams. FlatMap ( func ( interface { } ) [ ] interface { } )
streams. ForEach ( func ( interface { } ) )
streams. Reduce ( func ( interface { } , interface { } ) interface { } )
streams. GroupByKey ( func ( interface { } ) interface { } )
streams. GroupBy ( func ( interface { } ) interface { } , ... streams. Operation)
streams. Window ( streams. WindowConfig)
Execute ( streams. Source) streams. Result
go-streams应用案例
source := streams. NewSliceSource ( [ ] map [ string ] interface { } {
{ "name" : "Alice" , "age" : 18 } ,
{ "name" : "Bob" , "age" : 22 } ,
{ "name" : "Cathy" , "age" : 26 } ,
} )
pipeline := streams. NewPipeline (
streams. Map ( func ( item interface { } ) interface { } {
m := item. ( map [ string ] interface { } )
return Person{
Name: m[ "name" ] . ( string ) ,
Age: m[ "age" ] . ( int ) ,
}
} ) ,
streams. Filter ( func ( item interface { } ) bool {
return item. ( Person) . Age > 20
} ) ,
streams. Map ( func ( item interface { } ) interface { } {
p := item. ( Person)
return fmt. Sprintf ( "<person><name>%s</name><age>%d</age></person>" , p. Name, p. Age)
} ) ,
)
result := pipeline. Execute ( source)
fmt. Println ( result. Get ( ) )
七. 三方库 streams
streams库(https://github.com/razonyang/streams),一个用于处理数据流的第三方库。该库提供了类似Java 8 Stream API和.NET LINQ的API,支持各种常见的数据操作,如Map、Filter、Reduce等,还提供了一些其他的功能和扩展,包括:
迭代器(Iterator):提供了对数据源进行迭代遍历的功能 并行计算(Parallel computing):提供了对数据流进行并行处理的支持,可以充分利用多核CPU的优势 IO操作(IO operations):提供了对文件、网络等IO操作的支持,可以方便地进行读写操作 数据库操作(Database operations):提供了对关系型数据库的支持,可以使用SQL语句进行查询、插入、更新、删除 HTTP客户端(HTTP client):提供了对HTTP协议的客户端支持,可以方便地进行GET、POST、PUT、DELETE等
streams一下常用API
func New ( source interface { } ) * Stream
func of ( )
func ( s * Stream) FlatMap ( f interface { } ) * Stream
func ( s * Stream) Map ( mapper interface { } ) * Stream
func ( s * Stream) FlatMap ( mapper interface { } ) * Stream
func ( s * Stream) Filter ( predicate interface { } ) * Stream
func ( s * Stream) Distinct ( ) * Stream
func ( s * Stream) Skip ( n int ) * Stream
func ( s * Stream) Limit ( n int ) * Stream
func ( s * Stream) Sorted ( comparator interface { } ) * Stream
func ( s * Stream) Peek ( action interface { } ) * Stream
func ( s * Stream) ForEach ( action interface { } )
func ( s * Stream) Reduce ( identity, accumulator interface { } ) interface { }
func ( s * Stream) Collect ( collector interface { } ) interface { }
func ( s * Stream) GroupBy ( keyMapper interface { } ) map [ interface { } ] Group
func ( s * Stream) Join ( other * Stream, leftKeyMapper, rightKeyMapper, resultMapper interface { } ) * Stream
func ( s * Stream) AsSlice ( ) [ ] interface { }
func ( g Group) Key ( ) interface { }
func ( g Group) Stream ( ) * Stream
func ( ps * ParallelStream) Map ( mapper interface { } ) * ParallelStream
func ( ps * ParallelStream) FlatMap ( mapper interface { } ) * ParallelStream
func ( ps * ParallelStream) Filter ( predicate interface { } ) * ParallelStream
func ( ps * ParallelStream) Distinct ( ) * ParallelStream
func ( ps * ParallelStream) Skip ( n int ) * ParallelStream
func ( ps * ParallelStream) Limit ( n int ) * ParallelStream
func ( ps * ParallelStream) Sorted ( comparator interface { } ) * ParallelStream
func ( ps * ParallelStream) Peek ( action interface { } ) * ParallelStream
func ( ps * ParallelStream) ForEach ( action interface { } )
func ( ps * ParallelStream) Reduce ( identity, accumulator interface { } ) interface { }
func ( ps * ParallelStream) Collect ( collector interface { } ) interface { }
func ( ps * ParallelStream) GroupBy ( keyMapper interface { } ) map [ interface { } ] ParallelGroup
func ( ps * ParallelStream) Join ( other * ParallelStream, leftKeyMapper, rightKeyMapper, resultMapper interface { } ) * ParallelStream
func ( pg ParallelGroup) Key ( ) interface { }
func ( pg ParallelGroup) Stream ( ) * ParallelStream
八. 三方库 optional
optional(https://github.com/markphelps/optional)是 Go 语言的第三方库,提供了一种简洁而方便的方法来处理可选值,尤其是在处理可能为空的数据时非常有用 optional 库的核心是 Optional 类型,表示一个可选值。Optional 对象包含一个内部值value,以及一个标志位present,用于表示该值是否存在。当 present 为 false 时,value 可以为任何类型的零值,例如 nil、false、0 等,表示该可选值不存在;当 present 为 true 时,value 则表示实际的值 常用API总结
NewT ( value T) Optional
Present ( ) bool
Get ( ) T
OrElse ( defaultValue T) T
Map ( f func ( T) R) Optional[ R]
Filter ( predicate func ( T) bool ) Optional
OrElseGet ( supplier func ( ) T) T
IfPresent ( consumer func ( T) )
使用示例
import (
"fmt"
"github.com/markphelps/optional"
)
func GetString ( ) optional. String {
var str string
if ... {
return optional. NewString ( str)
} else {
return optional. String{ }
}
}
func main ( ) {
value := GetString ( )
uppercase := value. Map ( strings. ToUpper)
if uppercase. Present ( ) {
fmt. Println ( uppercase. Get ( ) )
} else {
fmt. Println ( "String is absent" )
}
defaultVal := value. OrElse ( "default" )
fmt. Println ( defaultVal)
filtered := value. Filter ( func ( s string ) bool {
return len ( s) > 5
} )
if filtered. Present ( ) {
fmt. Println ( filtered. Get ( ) )
} else {
fmt. Println ( "String is absent or too short" )
}
}
九. 三方库 maybe
maybe(https://github.com/xdg/scramjet),个提供了Maybe类型的库,支持类似于Scala中的集合Option类型的处理方式,能够更好地处理缺失值和错误信息等情况 Maybe 库的核心是 Maybe 类型,它表示一个可选值。Maybe 对象包含一个内部值value,以及一个标志位ok,用于表示该值是否存在。当 ok 为 false 时,value 可以为任何类型的零值,例如 nil、false、0 等,表示该可选值不存在;当 ok 为 true 时,value 则表示实际的值。 常用API总结
New ( value interface { } ) Maybe
Just ( value interface { } ) Maybe
Nothing ( ) Maybe
IsNothing ( ) bool
Unwrap ( ) interface { }
UnwrapOr ( def interface { } ) interface { }
Map ( f func ( interface { } ) interface { } ) Maybe
Default ( def interface { } ) Maybe
Filter ( f func ( interface { } ) bool ) Maybe
使用示例
package main
import (
"fmt"
"github.com/xdg/scramjet/maybe"
)
func main ( ) {
optionalValue := maybe. Just ( "Hello, Maybe!" )
fmt. Printf ( "The optional value is: %v\n" , optionalValue)
emptyValue := maybe. Nothing ( )
fmt. Printf ( "The empty value is: %v\n" , emptyValue)
value := optionalValue. Unwrap ( )
fmt. Printf ( "The value is: %v\n" , value)
isEmpty := emptyValue. IsNothing ( )
fmt. Printf ( "The empty value is nothing: %v\n" , isEmpty)
upperValue := optionalValue. Map ( func ( v interface { } ) interface { } {
s, ok := v. ( string )
if ! ok {
return ""
}
return strings. ToUpper ( s)
} )
fmt. Printf ( "The upper value is: %v\n" , upperValue)
defaultValue := emptyValue. Default ( "default" )
fmt. Printf ( "The default value is: %v\n" , defaultValue)
filteredValue := optionalValue. Filter ( func ( v interface { } ) bool {
s, ok := v. ( string )
if ! ok {
return false
}
return len ( s) > 5
} )
fmt. Printf ( "The filtered value is: %v\n" , filteredValue)
}
十. 针对上方数据处理三方库总结
市场使用角度:
目前来看,使用较广的库是 go-linq,根据 Github 上的数据,它有超过 4K 的 star 和大量的 fork,可以说是一个比较成熟和受欢迎的库 Golang-collections 提供了几种常见的数据结构,例如 Set、Deque、Queue 和 Stack,并且支持Filter、Map、Reduce、GroupBy、OrderBy 等,这些函数都是支持链式调用https://github.com/golang-collections/collections,并且有 2.9K 的 stars 虽然 go-streams 和 streams 也提供了流式处理的功能,但是它们的 star 数相对较少。在选择使用库的时候,除了考虑其功能是否满足需求之外,还需要考虑其文档资源、社区支持和开发者活跃度等因素
go-linq 优缺点:
优缺: 功能丰富,提供了丰富的 LINQ 风格的函数操作。底层采用指针和 Unsafe 等技术,性能较好。 缺点: 不支持链式操作。由于采用了 Unsafe 技术,存在一定的安全隐患。
go-streams 优缺点:
优点: 支持多种数据源,包括数组、切片、通道、文件等。支持链式操作,支持并行处理,可以运行在多个 CPU 上。 缺点: 依赖性较高,需要引入第三方库。函数操作相对较少,不如 go-linq 和 Golang-collections 丰富。
streams 优缺点:
优点: 支持链式操作,具有丰富的操作符,包括 Map、Filter、Reduce 等。 缺点:功能相对较少不如 go-linq 和 Golang-collections 丰富。底层实现性能可能略逊于 go-linq 和 Golang-collections。
Golang-collections优缺点:
优点: 提供了丰富的数据结构和集合操作函数,功能比较丰富。性能较好,底层采用了指针和 Unsafe 等技术。 缺点: 不支持链式操作,功能相对于 go-linq 和 go-streams 稍显简单。
综上所述,选择哪个三方库取决于具体需求。如果需要 LINQ 风格的操作,可以选择 go-linq;如果需要多种数据源和支持并行处理,可以选择 go-streams;如果需要丰富的数据结构和集合操作函数,可以选择 Golang-collections;而如果需要链式操作,可以选择 streams。