目录
  • 初识GoFrame
  • garray特点简介
  • 基本使用
    • 数组出栈
    • 包含判断
    • 排序数组
  • join、chunk、merge
    • 遍历
      • 遍历修改 walk函数
    • 序列化和反序列化
      • 总结

        写过PHP的同学都知道 PHP的数组Array非常好用,特别灵活。

        我在写PHP之前使用Java做安卓开发,在接触PHP的数组Array之后,直呼太香了!

        而在学习Go基础知识的时候了解到Go的数组和PHP的数组并不一样;从一定程度上讲,Go的slice切片类型和PHP的数组array比较像(不固定长度、引用类型、动态扩容等),但是在开发使用中远远不像PHP的array灵活。

        初识GoFrame

        最近在使用基于Go语言的GoFrame框架撸项目,发现GoFrame封装的garray竟然比PHP的array还要好用。

        近期已经更新了一系列GoFrame的文章,下文将GoFrame简称为gf。感兴趣的同学可以关注我的专栏:Go语言学习专栏 ,目前已经更新了86篇原创文章,获得了176位同学的关注。

        gf框架有个特点,提供的组件基本都支持设置并发安全开关。显然PHP是不支持并发安全开关的,PHP的数组是并发安全的。PHP-FPM是阻塞的单线程模型,PHP-FPM每个进程里只有一个线程,一个进程同时只能服务一个客户端。

        garray特点简介

        • garray支持int/string/interface{}三种常用的数据类型。
        • garray支持普通数组和排序数组,普通数组的结构体名称定义为Array格式,排序数组的结构体名称定义为SortedArray格式,如下:Array, intArray, StrArray,SortedArray, SortedIntArray, SortedStrArray
        • 其中排序数组SortedArray,需要给定排序比较方法,在工具包gutil中也定义了很多ComparatorXXX的比较方法,用起来很方便。当然也支持自定义排序方式。

        基本使用

        package main
        import (
           "fmt"
           "github.com/gogf/gf/container/garray"
        )
        func main() {
           //创建并发安全的int型数组
           a := garray.NewIntArray(true)
           //添加数组项
           for i := 0; i < 10; i++ {
              a.Append(i)
           }
           // 打印结果:
           fmt.Println(a) //"[0,1,2,3,4,5,6,7,8,9]"
           fmt.Println("数组长度:", a.Len())
           fmt.Println("数组的值:", a.Slice())
           fmt.Println((a.Get(5))) //根据索引取值 返回值和是否取到了值 5 true
           // 在指定索引前后插入值
           _ = a.InsertAfter(9, 10)
           _ = a.InsertBefore(0, -1)
           fmt.Println(a.Slice())
           // 搜索数据项,返回对应的索引
           fmt.Println("搜索值,返回对应索引:", a.Search(5))
           // 删除
           a.Remove(0)
           fmt.Println(a.Slice())
           // 并发安全 写锁操作
           a.LockFunc(func(array []int) {
              //将最后一项的值改为100
              array[len(array)-1] = 100
           })
           fmt.Println(a) //"[0,1,2,3,4,5,6,7,8,9,100]"
           // 并发安全 读锁操作
           a.RLockFunc(func(array []int) {
              fmt.Println(array[len(array)-1]) //100
           })
           // 清空数组
           a.Clear()
           fmt.Println("清空数组之后:", a.Slice())
        }
        

        打印结果

        GoFrame框架garray对比PHP的array优势

        数组出栈

        • 数组出栈使用Pop*关键字
        • 数组可以按顺序出栈,而gf提供的另外一个数据类型gmap的pop*方法是随机出栈 (关注我,会在后续的文章中更新说明)
        • garray中随机出栈,我们可以使用rand()或者popRand()
        package main
        import (
           "fmt"
           "github.com/gogf/gf/container/garray"
           "github.com/gogf/gf/frame/g"
        )
        //数组出栈 pop 数组可以按顺序出栈 map的pop是随机出栈
        func main() {
           a := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6})
           fmt.Println(a.PopLeft())
           fmt.Println(a.PopLefts(2))
           fmt.Println(a.PopRight())
           fmt.Println(a.PopRights(2))
           fmt.Println(a) //全部出栈后 数组为空
           /**
           打印结果:
           1 true
           [2 3]
           6 true
           [4 5]
           []
           */
           // 有什么办法能像map一样随机出栈呢? 在garray中我们使用rand()或者popRand()
           a1 := garray.NewFrom(g.Slice{1, 2, 3, 4, 5, 6, 7})
           fmt.Println("----------")
           fmt.Println(a1.Rand())      //随机取值
           fmt.Println(a1.PopRands(2)) //随机出栈
           fmt.Println(a1)
        }
        

        包含判断

        • 注意:Contains()是区分大小写
        • 空值过滤使用:FilterEmpty
        • nil过滤使用:FilterNil
        package main
        import (
           "github.com/gogf/gf/container/garray"
           "github.com/gogf/gf/frame/g"
        )
        //包含 contains 区分大小写
        func main() {
           var a garray.Array
           a.Append("a")
           g.Dump(a.Contains("a")) //true
           g.Dump(a.Contains("A")) //false
           // 空值过滤
           a1 := garray.NewFrom([]interface{}{0, 1, "2", nil, false, g.Slice{}, "王中阳"})
           a2 := garray.NewFrom([]interface{}{0, 1, "2", nil, false, g.Slice{}, "王中阳"})
           g.Dump("empty过滤:", a1.FilterEmpty()) //empty过滤:"[1,2,"王中阳"]"
           g.Dump("nil过滤:", a2.FilterNil())     //nil过滤:"[0,1,2,"false","[]","王中阳"]"
           a3 := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6, 7})
           g.Dump("数组翻转:", a3.Reverse())
           g.Dump("数组随机排序:", a3.Shuffle())
        }
        

        打印结果

        GoFrame框架garray对比PHP的array优势

        排序数组

        • 我们可以自定义NewSortedArray的排序规则,以实现是升序数组还是降序数组;
        • 排序数组还有唯一性校验的功能:garray.SetUnique(true)
        • gf框架的gutil工具包定义好了常用的排序规则
        package main
        import (
           "github.com/gogf/gf/container/garray"
           "github.com/gogf/gf/frame/g"
           "github.com/gogf/gf/util/gutil"
        )
        //我们可以自定义NewSortedArray的排序规则,以实现是升序数组还是降序数组;排序数组还有唯一性校验的功能
        func main() {
           //自定义排序数组:降序排列
           a := garray.NewSortedArray(func(a, b interface{}) int {
              if a.(int) < b.(int) {
                 return 1
              }
              if a.(int) > b.(int) {
                 return -1
              }
              return 0
           })
           // 排序规格可以使用gutil中定义好的
           a.Add(2) //数组的赋值用add map的赋值用set
           a.Add(1)
           a.Add(3)
           g.Dump("a:", a) //打印结果:"[3,2,1]"
           //升序数组
           a2 := garray.NewSortedArray(gutil.ComparatorInt)
           a2.Add(2)
           a2.Add(1)
           a2.Add(3)
           g.Dump("a2:", a2)
           // 添加重复元素
           a2.Add(2)
           g.Dump("a2添加重复元素后:", a2)
           a2.SetUnique(true) //设置不允许重复元素
           g.Dump("a2设置不允许重复元素之后:", a2)
        }
        

        打印结果

        GoFrame框架garray对比PHP的array优势

        join、chunk、merge

        • 数据项串联是相当常用的场景,比如多个id以逗号分隔入库存储,我们使用join关键字即可
        • garray支持将一个数组拆分成指定数量的二维数组,使用chunk关键字
        • garray支持使用merge关键字合并数组
        package main
        import (
           "fmt"
           "github.com/gogf/gf/container/garray"
           "github.com/gogf/gf/frame/g"
        )
        func main() {
           //join 串联 常用于逗号分割
           a := garray.NewFrom(g.Slice{1, 2, 3, 4, 5})
           fmt.Println("串联结果:", a.Join("_")) //1_2_3_4_5
           //数组拆分 chunk
           fmt.Println("数组拆分:", a.Chunk(2)) //[[1 2] [3 4] [5]]
           // 数组合并 可以合并数组 也可以合并slice(原生切片和g.Slice都支持)
           a1 := garray.NewFrom(g.Slice{1, 2})
           a2 := garray.NewFrom(g.Slice{3, 4})
           s1 := g.Slice{5, 6}
           s2 := []string{"7", "8"}
           s3 := []int{9, 0}
           a1.Merge(a2)
           a1.Merge(s1)
           a1.Merge(s2)
           a1.Merge(s3)
           fmt.Println("合并结果:", a1) // [1,2,3,4,5,6,7,8,9,0]
        }
        

        打印结果:

        GoFrame框架garray对比PHP的array优势

        遍历

        garray天然支持升序遍历和降序遍历

        函数Iterator()是IteratorAsc()的别名

        package main
        import (
           "fmt"
           "github.com/gogf/gf/container/garray"
           "github.com/gogf/gf/frame/g"
        )
        //数组遍历 iterate
        func main() {
           a := garray.NewFrom(g.Slice{"a", "b", "c"})
           fmt.Println("升序遍历结果")
           a.Iterator(func(k int, v interface{}) bool {
              fmt.Printf("%v,%v \n", k, v)
              return true
           })
           // 数组倒序遍历
           fmt.Println("倒序遍历结果:")
           a.IteratorDesc(func(k int, v interface{}) bool {
              fmt.Printf("%v,%v \n", k, v)
              return true
           })
        }
        

        打印结果

        GoFrame框架garray对比PHP的array优势

        遍历修改 walk函数

        非常好用!!!

        看到这个方法,更坚信了我一个观点:GF的作者一定写了几年PHP。

        package main
        import (
           "github.com/gogf/gf/container/garray"
           "github.com/gogf/gf/frame/g"
           "github.com/gogf/gf/util/gconv"
        )
        //walk遍历修改 修改数组的值
        func main() {
           var a garray.Array
           tables := g.Slice{"user", "user_detail"}
           a.Append(tables...)
           prefix := "gf_"
           a.Walk(func(value interface{}) interface{} {
              return prefix + gconv.String(value)
           })
           g.Dump(a)
        }
        

        打印结果

        GoFrame框架garray对比PHP的array优势

        序列化和反序列化

        这里重点提一下:gf container容器包下的对象都实现对原生json包的支持,都支持序列化和反序列化。

        gf非常重视对序列化的支持,Go学习专栏 文章中介绍了gmap、glist、gqueue、gset、gtree…等gf组件,都是支持序列化和反序列化的。

        打印结果

        GoFrame框架garray对比PHP的array优势

        总结

        综上我们了解到:

        • garray支持设置并发安全开关
        • 支持排序数组
        • 支持数组出栈、包含判断、join、chunk、merge等常用的工具方法
        • 天然支持升序遍历、遍历修改
        • 天然支持序列化和反序列化

        大家是不是明显感觉到GoFrame的garray比PHP的array还要好用。

        更加坚信GoFrame的作者是写过PHP的

        以上就是GoFrame框架garray对比PHP的array优势的详细内容,更多关于GoFrame框架garray优势的资料请关注其它相关文章!

        声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。