GoFrame框架garray对比PHP的array优势

目录
  • 打印结果
  • 打印结果
  • 打印结果
  • 打印结果:
  • 打印结果
  • 打印结果
  • 打印结果

写过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())
}
复制代码

打印结果

数组出栈

  • 数组出栈使用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())
}
复制代码

打印结果

排序数组

  • 我们可以自定义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)
}
复制代码

打印结果

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]
}
复制代码

打印结果:

遍历

  • 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
   })
}
复制代码

打印结果

遍历修改 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)
}
复制代码

打印结果

序列化和反序列化

  • 这里重点提一下:gf container容器包下的对象都实现对原生json包的支持,都支持序列化和反序列化。
  • gf非常重视对序列化的支持,Go学习专栏 文章中介绍了gmap、glist、gqueue、gset、gtree...等gf组件,都是支持序列化和反序列化的。

打印结果

总结

综上我们了解到:

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

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

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

作者:王中阳Go
链接:https://juejin.cn/post/7105012753210802213
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

(0)

相关推荐

  • GoFrame框架使用避坑指南和实践干货

    目录 gf gen dao 设置参数可不传 model作为结构体类型 使用with关联取值而不是join 不使用结构体批量添加数据 主程序如下: gomeGoods.MainImgs的定义: 插入数据 gf gen dao 生成dao层的脚手架工具很好用,我遇到的坑是这样的: 生成的dao文件和同事们的不一致,生成文件成功,但是对应的Columns是空的,虽然有这个方法,但是方法内没有值.我的版本比同事们的略高,我一直以为是这个原因,各种降级和同事保持一致的版本后还是不行. 最终发现:是配置文件

  • GoFrame gmap遍历hashmap listmap treemap使用技巧

    目录 先说结论 map类型 使用技巧 基础概念 对比sync.Map 基础使用 合并 merge 序列化 过滤空值 键值对反转 Flip 出栈(随机出栈) 总结 文章比较硬核,爆肝2千多字,除了hashmap.listmap.treemap使用技巧阅读还有使用gmap的踩坑之旅,阅读大约需要5~10分钟. 先说结论 map类型 一图胜千言: 实例化示例: hashMap := gmap.New(true) listMap := gmap.NewListMap(true) treeMap := g

  • GoFrame框架ORM原生方法对象操作开箱体验

    目录 前言 开箱体验 1. ORM对象 tips 2. 数据写入 3. 数据查询(单条) 4. 数据查询(列表) 5. 数据保存 6. 批量操作 tips 7. 数据更新/删除 tips 总结 前言 最近一直在用GoFrame(下文简称gf)来开发项目,在熟悉业务逻辑之后就是马不停蹄的撸代码了. 之前整理过结构体和json转换的文章:GoFrame必知必会之Scan:类型转换,今天整理同样比较重要的ORM相关的文章. gf是支持ORM原生操作的,在ORM链式操作执行不了太过于复杂的SQL操作时,

  • GoFrame框架garray并发安全数组使用开箱体验

    目录 前言 普通数组 Append At Chunk Clear Clone PopLefts 总结 前言 今天在搞一个需求,从三方获得有信息变更的商品,更新自己的数据库,再推送给下游进行商品更新. 期间有更新商品数量不确定,为了保证程序稳定性,每组向下游推送20个商品id. 查了garray的文档,发现支持Chunk()方法,灰常好用. func commonSendMessage(goodsIds *garray.IntArray, messageType int) { goodsIdsCh

  • GoFrame框架garray对比PHP的array优势

    目录 打印结果 打印结果 打印结果 打印结果: 打印结果 打印结果 打印结果 写过PHP的同学都知道 PHP的数组Array非常好用,特别灵活. 我在写PHP之前使用Java做安卓开发,在接触PHP的数组Array之后,直呼太香了! 而在学习Go基础知识的时候了解到Go的数组和PHP的数组并不一样:从一定程度上讲,Go的slice切片类型和PHP的数组array比较像(不固定长度.引用类型.动态扩容等),但是在开发使用中远远不像PHP的array灵活. 初识GoFrame 最近在使用基于Go语言

  • GoFrame框架gset使用对比PHP Java Redis优势

    目录 特点 使用入门 对比PHP和Java PHP JAVA GO原生 GoFrame 延伸 这篇文章将会为大家介绍GoFrame gset使用入门,为了让大家更好的理解,会简明扼要的分析一下集合类型Set的特点,对比一下Java.PHP.原生Go对集合Set类型的支持情况,如果不支持Set类型,我们如何找到解决方案,来实现元素不可重复性和交差并补集的需求. 特点 集合gset:一组不可重复的元素,元素可以是任何类型 上一篇文章介绍的: GoFrame的garray为什么比PHP的array还好

  • 适合PHP同学的GoFrame框架的使用体验及学习建议

    目录 前言 官方介绍 我的使用体验 设计思想 学习建议 有基础的同学 无基础的同学 官网地址 小坑 前言 今天继续为大家更新Go语言学习记录的文章,介绍最近发现的一款非常优秀的框架:GoFrame. 最近发现了一款非常好用的基于go语言的web开发框架,非常适合PHP转Go的同学使用,在很多设计思想和使用上和PHP的Laravel框架非常像. 今天就为大家简单介绍一下GoFrame的特点 官方介绍 GoFrame是一款模块化.高性能.企业级的Go基础开发框架.GoFrame不是一款WEB/RPC

  • C#中foreach循环对比for循环的优势和劣势

    前言 循环语句为众多程序员们提供了很大的便利,有while.do...while.for和 foreach.而且foreach语句很简洁,但是它的优点不仅仅在于此,它的效率也是最高的.本文将详细给大家关于C#中foreach循环对比for循环的优势和劣势,下面话不多说了,来一起看看详细的介绍吧. 一.foreach循环的优势 C#支持foreach关键字,foreach在处理集合和数组相对于for存在以下几个优势: 1.foreach语句简洁 2.效率比for要高(C#是强类型检查,for循环对

  • GoFrame框架gredis优雅的取值和类型转换

    目录 取值方法 不推荐 推荐 DoVar示例 ReceiveVar示例 HashSet示例 小技巧 总结 上一篇文章为大家介绍了 GoFrame gcache使用实践 | 缓存控制 淘汰策略 ,得到了大家积极的反馈. 后续几篇文章再接再厉,仍然为大家介绍GoFrame框架缓存相关的知识点,以及自己项目使用中的一些总结思考,GoFrame框架下文简称gf. 今天重点为大家介绍:GoFrame gredis 如何优雅的取值和类型转换 取值方法 不推荐 通过客户端方法Do/Receive获取的数据都是

  • GoFrame 框架缓存查询结果的示例详解

    目录 查询缓存 相关方法: 缓存对象 缓存适配(Redis缓存) 使用示例 数据表结构 示例代码 小技巧 运行结果分析 总结 后续几篇文章再接再厉,仍然为大家介绍GoFrame框架缓存相关的知识点,以及自己项目使用中的一些总结思考,GoFrame框架下文简称gf. 今天重点为大家介绍:GoFrame 如何优雅的缓存查询结果 查询缓存 gdb支持对查询结果的缓存处理,常用于多读少写的查询缓存场景,并支持手动的缓存清理. 需要注意的是,查询缓存仅支持链式操作,且在事务操作下不可用. 相关方法: fu

  • 阿里云盘对比百度网盘优势分析(阿里云盘邀请码、内测码获取方法) 原创

    阿里巴巴开始预告推出阿里云盘以后,很多小伙伴都在关注这个事情,作为一家非常有实力的IT互联网公司,这个重磅产品一定会改变目前市场中网盘的格局,由于更推出,并且注册通过激活码邀请码的方式,很多朋友都没有能够提前体验到这款产品,为了回馈小伙伴对我们的支持,我们通过渠道获取了珍贵的9个激活码,在文末免费分享给大家! 阿里云网盘官网 阿里云盘官网:https://www.aliyundrive.com/ 阿里云官网截图 阿里云盘免费空间多大 1.阿里云网盘app免费的容量空间是1TB,如果是开放会员的话

随机推荐