脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - GoFrame的数组比PHP的数组还好用?

GoFrame的数组比PHP的数组还好用?

2022-10-26 20:03程序员升级打怪之旅王中阳Go Golang

而在学习Go基础知识的时候了解到Go的数组和PHP的数组并不一样;从一定程度上讲,Go的slice切片类型和PHP的数组array比较像(不固定长度、引用类型、动态扩容等),但是在开发使用中远远不像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语言学习专栏 ,目前已经更新了120多篇原创文章,获得了700多位同学的关注。

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的数组比PHP的数组还好用?

数组出栈

  • 数组出栈使用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的数组比PHP的数组还好用?

排序数组

我们可以自定义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的数组比PHP的数组还好用?

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的数组比PHP的数组还好用?

遍历

  • 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的数组比PHP的数组还好用?

遍历修改 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的数组比PHP的数组还好用?

序列化和反序列化

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

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

package main

import ( "encoding/json" "fmt" "github.com/gogf/gf/container/garray" "github.com/gogf/gf/frame/g" ) //gf container容器包下的对象都实现对原生json包的支持,即都支持序列化和反序列化
func main() { //序列化
   type student struct { Name   string
      Age int Scores *garray.IntArray } s := student{ Name: "王中阳", Age: 28, Scores: garray.NewIntArrayFrom([]int{100, 98}), } bytes, _ := json.Marshal(s) g.Dump(bytes) //{"Name":"王中阳","Age":28,"Scores":[100,98]} //反序列化
   data := []byte(`{"Name":"王中阳","Age":28,"Scores":[100,98]}`) s2 := student{} _ = json.Unmarshal(data, &s2) fmt.Println(s2) //{王中阳 28 [100,98]} }

打印结果

GoFrame的数组比PHP的数组还好用?

总结

综上我们了解到:

  • garray支持设置并发安全开关
  • 支持排序数组
  • 支持数组出栈、包含判断、join、chunk、merge等常用的工具方法
  • 天然支持升序遍历、遍历修改
  • 天然支持序列化和反序列化
  • 大家是不是明显感觉到GoFrame的garray比PHP的array还要好用。

本文转载自微信公众号「 程序员升级打怪之旅」,作者「王中阳Go」,可以通过以下二维码关注。

GoFrame的数组比PHP的数组还好用?

原文地址:https://mp.weixin.qq.com/s/laqGES5MajRJBPbkq5Suzw

延伸 · 阅读

精彩推荐
  • GolangGo语言中并发的工作原理

    Go语言中并发的工作原理

    本文详细讲解了Go语言中并发的工作原理,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...

    奋斗的大橙子8912022-07-16
  • Golanggolang如何使用struct的tag属性的详细介绍

    golang如何使用struct的tag属性的详细介绍

    这篇文章主要介绍了golang如何使用struct的tag属性的详细介绍,从例子说起,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看...

    Go语言中文网8922020-05-21
  • Golanggolang三元表达式的使用方法

    golang三元表达式的使用方法

    这篇文章主要介绍了golang三元表达式的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    daihepeng14512021-04-21
  • Golang一步步教你编写可测试的Go语言代码

    一步步教你编写可测试的Go语言代码

    相信每位编程开发者们应该都知道,Golang作为一门标榜工程化的语言,提供了非常简便、实用的编写单元测试的能力。本文通过Golang源码包中的用法,来学...

    tabalt4472020-05-04
  • Golanggolang创建文件目录os.Mkdir,os.MkdirAll的区别说明

    golang创建文件目录os.Mkdir,os.MkdirAll的区别说明

    本文主要讲述os.Mkdir、os.MkdirAll区别以及在创建文件目录过程中的一些其他技巧,希望对大家有所帮助。一起跟随小编过来看看吧...

    wade30159642021-04-18
  • GolangGo 修改map slice array元素值操作

    Go 修改map slice array元素值操作

    这篇文章主要介绍了Go 修改map slice array元素值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    周伯通的麦田12372021-03-18
  • GolangGo语言学习之映射(map)的用法详解

    Go语言学习之映射(map)的用法详解

    Map是一种无序的键值对的集合。这篇文章主要为大家详细介绍了Go语言中映射的用法,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的可...

    隐姓埋名486911822022-09-26
  • GolangGoFrame的数组比PHP的数组还好用?

    GoFrame的数组比PHP的数组还好用?

    而在学习Go基础知识的时候了解到Go的数组和PHP的数组并不一样;从一定程度上讲,Go的slice切片类型和PHP的数组array比较像(不固定长度、引用类型、动态扩...

    程序员升级打怪之旅4712022-10-26