常用代码包

* 本页面主要介绍Go语言的相关内容。

在Go编程过程中,我们经常会用到一些已经封装好的功能包,来实现一些功能和逻辑。这篇的目的就是帮大家总结和推荐一些常用的包和使用方法,便于大家提升开发效率和查阅。

一、“格式化”包:fmt

开发过程中,我们经常会遇到“格式化”的场景,这个时候,就可以使用fmt包:fmt包含有格式化I/O函数,类似于C语言的printf和scanf。格式字符串的规则来源于C,但更简单一些。

  • Print:输出给定的字符串,如果是数值或字符,则输出对应的十进制表示
  • Println:自动在结尾输出\n,两个数值之间自动加空格,每项之间自动加空格
  • Printf:格式化输出,常用的格式化见下面列举:
  通用:
  %v    值的默认格式表示
  %+v    类似%v,但输出结构体时会添加字段名
  %#v    值的Go语法表示
  %T    值的类型的Go语法表示
  %%    百分号

  布尔值:
  %t    true或false

  整数:
  %b    表示为二进制
  %c    该值对应的unicode码值
  %d    表示为十进制
  %o    表示为八进制
  %q    该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
  %x    表示为十六进制,使用a-f
  %X    表示为十六进制,使用A-F
  %U    表示为Unicode格式:U+1234,等价于"U+%04X"

  浮点数与复数:
  %b    无小数部分、二进制指数的科学计数法,如-123456p-78;参见strconv.FormatFloat
  %e    科学计数法,如-1234.456e+78
  %E    科学计数法,如-1234.456E+78
  %f    有小数部分但无指数部分,如123.456
  %F    等价于%f
  %g    根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
  %G    根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)

  字符串和[]byte:
  %s    直接输出字符串或者[]byte
  %q    该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示
  %x    每个字节用两字符十六进制数表示(使用a-f)
  %X    每个字节用两字符十六进制数表示(使用A-F)

  指针:
  %p    表示为十六进制,并加上前导的0x  
二、“字符串”包:strings

strings标准库包主要涉及字符串的基本操作。常见操作如下:

  1、Index
  输出第一个字符(从左到右)的序号 
  如:strings.Index("suoning","n") 结果:3
  2、LastIndex
  输出最后一个(和上面相反)  
  如:strings.LastIndex("suoning","n") 结果:5
  3、Replace
  替换 大于0的数表示替换几个,0不替换,小于0替换所有 
  如:strings.Replace("suoning","n","#",-1 ) 结果:suo#i#g
  4、HasPrefix
  类似python的startswith,判断以什么开头,返回true和false ,
  如:strings.HasPrefix("suoning","suo") 结果:true
  5、HasSuffix
  判断以什么结尾,类似python的endswith 
  如:strings.HasSuffix("suoning","ning") 结果:true
  6、Contains
  判断字符串s是否包含子串s1 
  如:strings.Contains("suoning","suoni")  结果:true
  7、Count
  出现的次数(计数) 
  如:strings.Count("nnnnnn","n")  结果:6
  8、Repeat
  字符串*n 
  如:strings.Repeat("n", 6)  结果: nnnnnn
  9、ToLower
  所有字母小写 
  如:strings.ToLower("SuoNing") 结果:suoning
  10、ToUpper
  所有字母大写 
  如:strings.ToUpper("suoning")  结果:SUONING
  11、TrimSpace
  去掉前后端的所有空格 
  如:strings.TrimSpace("  \nsuoning\n  ")) 结果:nsuoning
  12、Trim
  将前后端所有符合条件的字符串去掉 
  如:strings.Trim("!!suoning!!","!")    结果:su!oning
  13、TrimLeft
  所有前端符合条件的字符串去掉 
  如:strings.TrimLeft("!suoning!","!") 结果:su!oning!
  14、TrimRight
  所有符合后端的字符串去掉 
  如:strings.TrimRight("!suoning!","!") 结果:!su!oning
  15、Fields
  按照空格分割的多个字符串 
  如:strings.Fields(" suo ning ") 结果:[suo ning]
  16、Split
  分割   
  如:strings.Split(",suo,ning,",",") 结果:[ suo ning ]
  17、Join
  拼接  
  如:strings.Join([]string{"abcd","ddd"}," ") 结果:abcd ddd
三、“时间”包:time

与时间相关的各种需求,可以借助time包来实现。时间可分为时间点与时间段,golang 也不例外,提供了以下两个基础类型。除此之外 golang 也提供了三个特殊类型,做一些特定的业务。

  • 时间点(Time)
  • 时间段(Duration)
  • 时区(Location)
  • Ticker
  • Timer(定时器)

对于time包的常见使用场景,总结如下:

  1、Now 
  当前时间 
  如:time.Now() 结果:2019-03-04 15:33:25.044013971 +0800 CST m=+0.000231204
  2、Unix 
  时间戳  
  如:time.Now().Unix() 结果:1551684901
  3、Stamp  
  时间(没有年月日,只精确到s) 
  如:time.Stamp 结果:Jan _2 15:04:05
  4、Date  
  指定时间  
  如:time.Date(2008, time.November, 11, 23, 0, 0, 0, time.UTC) 结果:2008-11-11 23:00:00 +0000 UTC
  5、Format 
  格式输出时间 
  如:time.Now().Format("2006-1-02 15:04:05" )//必须使用这个时间才行2006-1-02 15:04:05  结果:2019-3-04 15:48:01
  6、ParseDuration   
  添加或减少时间 
  如:t,_ := time.ParseDuration("-10m")//小时为-10h ,天为
     Println(time.Now().Add(t))   结果: 2019-03-04 15:55:21.436413622 +0800 CST m=-599.999598120
  7、Sleep   
  睡眠时间, time.Second为秒 
  如:time.Sleep(time.Second*10) 睡眠10秒

  //时间常量
  Microsecond   微秒
  Millisecond   毫秒
  Second        秒
  Minute        分钟
  Hour          小时
四、“随机数”包:math/rand

math/rand 实现了伪随机数生成器。使用方法如下:

package main
  import (
      "math/rand"
      "fmt"
      "time"
  )
   
  func init() {
      rand.Seed(time.Now().UnixNano())//使用给定的seed来初始化生成器到一个确定的状态。
  }
   
  func main() {
      fmt.Println(rand.Int())    //9153536921449289609(返回一个非负的伪随机int值)
      fmt.Println(rand.Int31())  //2037735069(返回一个int32类型的非负的31位伪随机数)
      fmt.Println(rand.Int63())  //1132646811815532030(返回一个int64类型的非负的63位伪随机数)
      fmt.Println(rand.Intn(100))//95(取值范围在[0,n)的伪随机int值,n<=0会panic)
      fmt.Println(rand.Float32())//0.09178123(取值范围在[0.0, 1.0)的伪随机float32值)
      fmt.Println(rand.Perm(5))  //[0 4 1 2 3](有n个元素的,[0,n)范围内整数的伪随机排列的切片)
  }

  结果:
  8550661205998522408
  1835614409
  8970669406830364302
  79
  0.19600172
  [1 3 0 2 4]
五、“系统”包:os

os 包实现了系统相关的操作和读取。使用方法如下:

  1、Hostname   主机名 如:os.Hostname() 结果:localhost.localdomain 
  2、Getpagesize 返回底层的系统内存页的尺寸  如:os.Getpagesize() 结果:4096
  3、Environ  查看环境变量 如:os.Environ()
  4、Getenv  获取环境变量的值 如:os.Getenv("SHELL") 结果:/bin/bash
  5、Setenv 设置环境变量  如:os.Setenv("a","b")//设置环境变量a值为b
  6、Clearenv  删除所有环境变量  如:os.Clearenv()
  7、Exit  退出程序,并返回给的状态码   如:os.Exit(2)  结果:exit status 2
  8、Getuid 调用者的用户ID  如:os.Getuid()//使用的root 结果:0
  9、Geteuid 调用者的有效用户ID 如:os.Geteuid() 结果:0
  10、Getgid 调用者的组ID  如:os.Getgid() 结果:0
  11、Getegid 调用者的有效组ID  如:os.Getegid() 结果:0
  12、Getgroups 调用者所属的所有用户组的组ID 如:os.Getgroups() 结果:[0] 
  13、Getpid 调用者所在进程的进程ID 如:os.Getpid() 结果:116742
  14、Getppid 调用者所在进程的父进程的进程ID 如:os.Getppid() 结果:116725
  15、Getwd   当前所在路径(类似shell的pwd) 如:os.Getwd() 结果:/data/go 
  16、Chdir 更改当前所在目录(类似shell的cd) 如:os.Chdir("/tmp/") //切换到/tmp目录下
  17、Mkdir  创建目录(shell的mkdir一样) 如:os.Mkdir("/tmp/test")
  18、MkdirAll  递归创建目录(shell的mkdir -p) 如:os.MkdirAll("/tmp/test1/test2/test3")
  19、Rename  更改文件或目录的名字 如:os.Rename("/tmp/test1","/tmp/test2")
  20、Remove  删除文件或目录  如:os.Remove("/tmp/test2/test2") 
  21、RemoveAll 递归删除 如:os.RemoveAll("/tmp/test1/")
  22、Create  创建文件,存在会清空  如:os.Create("/tmp/test")
  23、Open  打开文件 如:os.Open("/tmp/test")
六、“命令行参数”包:flag

flag包,可以方便的解析命令行参数,而且参数顺序可以随意。使用方法如下:

  [root@localhostgo_test]#cat flag.go 
  package main
  import (
      "fmt"
      "flag"
  )

  func main(){
      var user string 
      var password string 
      var host string 
      var port int 
      

      //"u"指的-u是user参数
      flag.StringVar(&user,"u","root","用户名,默认为root")
      flag.StringVar(&password,"p","","默认为空")
      flag.StringVar(&host,"h","localhost","host参数,默认localhost")
      flag.IntVar(&port,"port",999,"端口")
      //转换,必须调用该方法
      flag.Parse()
      fmt.Println(user,password,host,port)
   
  }
  [root@localhostgo_test]#go run  flag.go  -u root -p 123456  -h 192.168.1.1   -port 9999
  root 123456 192.168.1.1 9999
七、“json序列化”包:encoding/json

json的序列化和反序列化是我们开发场景中最常遇到的,关于json的知识,详见 JSON 一节。encoding/json包的使用方法如下:

  package main
  import ( 
      "fmt" 
      "encoding/json"
  )

  //定义一个结构体
  type Monster struct {
      Name string `json:"json_name"` //`json:"xxx"` 反射使用
      Age int     `json:"age_test"`
      Sal float64
      Skill string
  }

  func testStruct() {
      //演示
      monster := Monster{
          Name :"张三", 
          Age : 20, 
          Sal : 8000.0,
          Skill : "普通拳",
      }
      //将 monster 序列化
      data, err := json.Marshal(&monster)
      if err != nil {
          fmt.Printf("序列号错误 err=%v\n", err)
      }
      //输出序列化后的结果
      fmt.Printf("struct序列化后=%v\n", string(data))
  }

  //将 map 进行序列化
  func testMap() {
      //定义一个 map
      var a map[string]interface{}
      //使用 map,需要 make
      a = make(map[string]interface{})
      a["name"] = "李四" 
      a["age"] = 30
      a["sal"] =  5000
      a["skill"] = "剑" 
      //将 a 这个 map 进行序列化
      data, err := json.Marshal(a)
      if err != nil {
          fmt.Printf("序列化错误 err=%v\n", err)
      }
      //输出序列化后的结果
      fmt.Printf("map 序列化后=%v\n", string(data))
  }

  //切片序列化
  func testSlice() {
      var slice []map[string]interface{}
      var m1 map[string]interface{}
      //使用 map 前,需要先 make
      m1 = make(map[string]interface{})
      m1["name"] = "jack" 
      m1["age"] = "7" 
      m1["address"] = "北京"
      slice = append(slice, m1)
      var m2 map[string]interface{}
      //使用 map 前,需要先 make
      m2 = make(map[string]interface{})
      m2["name"] = "王五"
      m2["age"] = "21" 
      m2["address"] = [2]string{"墨西哥","夏威夷"}
      slice = append(slice, m2)
      //将切片进行序列化操作
      data, err := json.Marshal(slice)
      if err != nil {
          fmt.Printf("序列化错误 err=%v\n", err)
      }
      //输出序列化后的结果
      fmt.Printf("slice 序列化后=%v\n", string(data))
  }

  //对基本数据类型序列化,对基本数据类型进行序列化意义不大
  func testFloat64() {
      var num1 float64 = 2345.67
      //对 num1 进行序列化
      data, err := json.Marshal(num1)
      if err != nil {
          fmt.Printf("序列化错误 err=%v\n", err)
      }
      //输出序列化后的结果
      fmt.Printf("float64 序列化后=%v\n", string(data))
  }

  func main(){
      testStruct()
      fmt.Println("========================")
      testMap()
      fmt.Println("========================")
      testSlice()
      fmt.Println("========================")
      testFloat64()  
      

  }



  ###########结果############
  struct序列化后={"json_name":"张三","age_test":20,"Sal":8000,"Skill":"普通拳"}
  ========================
  map 序列化后={"age":30,"name":"李四","sal":5000,"skill":"剑"}
  ========================
  slice 序列化后=[{"address":"北京","age":"7","name":"jack"},{"address":["墨西哥","夏威夷"],"age":"21","name":"王五"}]
  ========================
  float64 序列化后=2345.67
  package main
  import ( 
      "fmt"
      "encoding/json"
  )
  //定义一个结构体
  type Monster struct {
      Name string
      Age int
      Birthday string  
      Sal float64
      Skill string
  }
  //演示将 json 字符串,反序列化成 struct
  func unmarshalStruct() {
      //说明 str 在项目开发中,是通过网络传输获取到.. 或者是读取文件获取到
      str := "{\"Name\":\"牛魔王\",\"Age\":500,\"Birthday\":\"2011-11-11\",\"Sal\":8000,\"Skill\":\"牛魔拳\"}"
      //定义一个 Monster 实例
      var monster Monster
      err := json.Unmarshal([]byte(str), &monster)
      if err != nil {
          fmt.Printf("unmarshal err=%v\n", err)
      }
      fmt.Printf("反序列化后 monster=%v monster.Name=%v \n", monster, monster.Name)
  }
  //演示将 json 字符串,反序列化成 map
  func unmarshalMap() {
      str := "{\"address\":\"洪崖洞\",\"age\":30,\"name\":\"红孩儿\"}"
      //定义一个 map
      var a map[string]interface{}
      //反序列化
      //注意:反序列化 map,不需要 make,因为 make 操作被封装到 Unmarshal 函数
      err := json.Unmarshal([]byte(str), &a)
      if err != nil {
          fmt.Printf("unmarshal err=%v\n", err)
  }
      fmt.Printf("反序列化后 a=%v\n", a)
  }
  //演示将 json 字符串,反序列化成切片
  func unmarshalSlice() {
      str := "[{\"address\":\"北京\",\"age\":\"7\",\"name\":\"jack\"}," +
      "{\"address\":[\"墨西哥\",\"夏威夷\"],\"age\":\"20\",\"name\":\"tom\"}]"
      //定义一个 slice
      var slice []map[string]interface{}
      //反序列化,不需要 make,因为 make 操作被封装到 Unmarshal 函数
      err := json.Unmarshal([]byte(str), &slice)
          if err != nil {
          fmt.Printf("unmarshal err=%v\n", err)
      }
      fmt.Printf("反序列化后 slice=%v\n", slice)
  }
  func main() {
      unmarshalStruct()
      fmt.Println("===============")
      unmarshalMap()
      fmt.Println("===============")
      unmarshalSlice()
  }




  ##############结果###########
  反序列化后 monster={牛魔王 500 2011-11-11 8000 牛魔拳} monster.Name=牛魔王 
  ===============
  反序列化后 a=map[address:洪崖洞 age:30 name:红孩儿]
  ===============
  反序列化后 slice=[map[address:北京 age:7 name:jack] map[address:[墨西哥 夏威夷] age:20 name:tom]]

* 本页内容参考以下数据源:

  • 《Go程序设计语言》
  • https://www.cnblogs.com/jiangchunsheng/p/10725053.html
  • https://www.cnblogs.com/zhangb8042/p/10496120.html
  • https://blog.csdn.net/wschq/article/details/80114036

凯冰科技 · 代码改变世界,技术改变生活
下一节:反射 →