gobox中的异常定义和杂项工具

https://mp.weixin.qq.com/s/F-T9aoo3-DMAEr8-dzsenQ
Agang 360技术 360技术 微信号 qihoo_tech 功能介绍 360公司官方技术号,打造360最专业的技术聚合平台。 5天前

奇技指南

今天给大家介绍下我们自主开发的go语言轻型框架gobox,分享它的由来以及gobox中的异常定义和杂项工具。

gobox简介

gobox我们自主开发的go语言轻型框架

目前它的项目地址为:

https://github.com/goinbox

前世今生

我最开始用go写的第一个项目是一个代码发布系统,里面参考Raft实现了一套代码发布机故障自动检测恢复的机制。

那个时候刚刚接触go语言,开发时用到的一些库都是仿照之前用别的语言开发时的库用go重新实现的,随着我对go越来越熟悉,项目中用的也越来越多,我们重构了这个库,并命名为gobox。

随着go官方推出了dep这个包管理工具,我们把gobox中的每一个box都单独拿出来作为一个项目管理,这就是现在的gobox:

https://github.com/goinbox。

命名的由来

为什么叫gobox呢?

因为我们设计让每一个单独的模块都作为一个box,那这些box的集合就称为gobox,再使用go的pkg管理机制引入到项目中。

目前支持的box

  1. ├── color // 为终端输出增加颜色
  2. ├── crypto // 常用加解密相关
  3. ├── encoding // 常用编解码相关
  4. ├── exception // 用errno+msg表示的错误
  5. ├── gohttp // http服务相关
  6. ├── golog // log记录相关
  7. ├── gomisc // 零碎的工具库
  8. ├── go-nsq-mate // 配合操作nsq队列
  9. ├── inotify // 文件系统通知
  10. ├── levelcache // 使用leveldb实现的本地cache
  11. ├── mysql // mysql操作相关
  12. ├── page // 分页操作
  13. ├── pool // 连接池实现
  14. ├── redis // redis操作相关
  15. ├── shardmap // 为减小map锁粒度实现的碎片化map
  16. ├── shell // 执行shell命令相关
  17. ├── simplecache // 内存cache

使用方式

每个box都相当于一个pkg,使用也很简单,示例:

  1. package main
  2. import (
  3. "github.com/goinbox/color"
  4. "fmt"
  5. )
  6. func main() {
  7. fmt.Println(string(color.Black([]byte("Black"))))
  8. fmt.Println(string(color.Red([]byte("Red"))))
  9. fmt.Println(string(color.Green([]byte("Green"))))
  10. fmt.Println(string(color.Yellow([]byte("Yellow"))))
  11. fmt.Println(string(color.Blue([]byte("Blue"))))
  12. fmt.Println(string(color.Maganta([]byte("Maganta"))))
  13. fmt.Println(string(color.Cyan([]byte("Cyan"))))
  14. fmt.Println(string(color.White([]byte("White"))))
  15. }

go官方提供了dep工具,配合在项目中使用可以更加方便。

  1. dep https://golang.github.io/dep/

exception

很多语言提供了异常机制,但是go没有,相似的能力可以用panic/recover来模拟,但是官方并不推荐这样做。

我们在系统中定义错误时通常需要错误码errno和错误信息msg,这个包就是简单的包装了下这两个常用的错误内容。

用法示例

  1. package main
  2. import (
  3. "github.com/goinbox/exception"
  4. "fmt"
  5. )
  6. func main() {
  7. e := exception.New(101, "test exception")
  8. fmt.Println(e.Errno(), e.Msg())
  9. fmt.Println(e.Error())
  10. }

输出效果示例

  1. 101 test exception
  2. errno: 101, msg: test exception

gomisc

gomisc提供了很多工具方法

slice去重

这里仅对最常用的int[]string[]提供了方法,示例:

  1. package main
  2. import (
  3. "github.com/goinbox/gomisc"
  4. "fmt"
  5. )
  6. func main() {
  7. is := []int{1, 2, 2, 3, 3, 3, 4, 4, 4, 4}
  8. fmt.Println("origin slice is: ", is)
  9. is = gomisc.IntSliceUnique(is)
  10. fmt.Println("after call slice is: ", is)
  11. ss := []string{"a", "ab", "ab", "abc", "abc", "abc", "abcd", "abcd", "abcd", "abcd", "abcd"}
  12. fmt.Println("origin slice is: ", ss)
  13. ss = gomisc.StringSliceUnique(ss)
  14. fmt.Println("after call slice is: ", ss)
  15. }

结果输出:

  1. origin slice is: [1 2 2 3 3 3 4 4 4 4]
  2. after call slice is: [1 2 3 4]
  3. origin slice is: [a ab ab abc abc abc abcd abcd abcd abcd abcd]
  4. after call slice is: [a ab abc abcd]

检查文件或是目录是否存在

示例:

  1. package main
  2. import (
  3. "github.com/goinbox/gomisc"
  4. "fmt"
  5. )
  6. func main() {
  7. f := "/etc/passwd"
  8. r := gomisc.FileExist(f)
  9. if r {
  10. fmt.Println(f, "is exist")
  11. } else {
  12. fmt.Println(f, "is not exist")
  13. }
  14. d := "/home/ligang/devspace"
  15. r = gomisc.DirExist(d)
  16. if r {
  17. fmt.Println(d, "is exist")
  18. } else {
  19. fmt.Println(d, "is not exist")
  20. }
  21. }

结果输出:

  1. /etc/passwd is exist
  2. /home/ligang/devspace is exist

[]byte追加

示例:

  1. package main
  2. import (
  3. "github.com/goinbox/gomisc"
  4. "fmt"
  5. )
  6. func main() {
  7. b := []byte("abc")
  8. b = gomisc.AppendBytes(b, []byte("def"), []byte("ghi"))
  9. fmt.Println(string(b))
  10. }
  11. 结果输出:
  12. abcdefghi
  13. 递归获取指定根目录下的所有文件,包括子目录
  14. 这里的实现,解决了目录过深时栈溢出的问题,示例:
  15. package main
  16. import (
  17. "github.com/goinbox/gomisc"
  18. "fmt"
  19. )
  20. func main() {
  21. fileList, err := gomisc.ListFilesInDir("/home/ligang/tmp")
  22. if err != nil {
  23. fmt.Println(err)
  24. return
  25. }
  26. for _, path := range fileList {
  27. fmt.Println(path)
  28. }
  29. }

输出:

  1. root dir is: /home/ligang/tmp
  2. file list under root dir are:
  3. /home/ligang/tmp/misc/go1.10.2.linux-amd64.tar.gz
  4. /home/ligang/tmp/misc/CLion-2018.1.2.tar.gz
  5. /home/ligang/tmp/misc/docker-18.03.1-ce.tgz
  6. /home/ligang/tmp/go/main.go
  7. /home/ligang/tmp/go/.idea/modules.xml
  8. /home/ligang/tmp/go/.idea/workspace.xml
  9. /home/ligang/tmp/go/.idea/go.iml

保存和解析json文件

示例:

  1. package main
  2. import (
  3. "github.com/goinbox/gomisc"
  4. "fmt"
  5. )
  6. func main() {
  7. filePath := "/tmp/test_save_parse_json_file.json"
  8. v1 := make(map[string]string)
  9. v1["k1"] = "a"
  10. v1["k2"] = "b"
  11. v1["k3"] = "c"
  12. err := gomisc.SaveJsonFile(filePath, v1)
  13. if err != nil {
  14. fmt.Println("save json file failed: " + err.Error())
  15. } else {
  16. fmt.Println("save json file success")
  17. }
  18. v2 := make(map[string]string)
  19. err = gomisc.ParseJsonFile(filePath, &v2)
  20. if err != nil {
  21. fmt.Println("parse json file failed: " + err.Error())
  22. } else {
  23. fmt.Println("parse json file success")
  24. }
  25. for k, v := range v2 {
  26. if v != v1[k] {
  27. fmt.Println("save parse json file error, k: " + k + " not equal")
  28. } else {
  29. fmt.Println("save parse json file k:", k, "equal")
  30. }
  31. }
  32. }

输出:

  1. end too long
  2. end too long
  3. abcdefg substr 3,4 is defg

字符串截取

示例:

  1. package main
  2. import (
  3. "github.com/goinbox/gomisc"
  4. "fmt"
  5. )
  6. func main() {
  7. s := "abcdefg"
  8. _, err := gomisc.SubString(s, 3, 20)
  9. fmt.Println(err)
  10. _, err = gomisc.SubString(s, 10, 3)
  11. fmt.Println(err)
  12. ss, _ := gomisc.SubString(s, 3, 4)
  13. fmt.Println(s, "substr", "3,4", "is", ss)
  14. }

输出:

  1. end too long
  2. end too long
  3. abcdefg substr 3,4 is defg

时间格式化时的常量定义

  1. TIME_FMT_STR_YEAR = "2006"
  2. TIME_FMT_STR_MONTH = "01"
  3. TIME_FMT_STR_DAY = "02"
  4. TIME_FMT_STR_HOUR = "15"
  5. TIME_FMT_STR_MINUTE = "04"
  6. TIME_FMT_STR_SECOND = "05"

常用时间格式化时的格式

输出格式: yyyy-mm-dd h:i:s

示例:

  1. package main
  2. import (
  3. "github.com/goinbox/gomisc"
  4. "fmt"
  5. "time"
  6. )
  7. func main() {
  8. layout := gomisc.TimeGeneralLayout()
  9. fmt.Println("fmt layout is", layout)
  10. fmt.Println("not time is", time.Now().Format(layout))
  11. }

输出:

  1. fmt layout is 2006-01-02 15:04:05
  2. not time is 2018-05-20 06:15:08

通过时间生成随机数

示例:

  1. package main
  2. import (
  3. "github.com/goinbox/gomisc"
  4. "fmt"
  5. "time"
  6. )
  7. func main() {
  8. tm := time.Now()
  9. fmt.Println(gomisc.RandByTime(&tm), gomisc.RandByTime(&tm), gomisc.RandByTime(nil))
  10. }

输出:

  1. 4423491624236117727 4423491624236117727 1471010178475409526

这里请注意:时间值相同时运算结果是相同的。

欢迎大家使用gobox,使用中有遇到问题,可在公众号后台反馈,我们会尽快响应,谢谢~~

ft_authoradmin  ft_create_time2019-06-02 13:38
 ft_update_time2019-06-02 13:38