加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang内置常用包

发布时间:2020-12-16 09:22:53 所属栏目:大数据 来源:网络整理
导读:strings 字符串函数 Contains(s,substr string) bool 字符串s是否包含字符串substr,包含返回true Split(s,sep string) []string 将字符串s按照分隔符sep分隔为slice Join(a []string,sep string) string 字符串拼接,把slice a通过sep链接起 Trim(s string,

strings 字符串函数

  • Contains(s,substr string) bool
    字符串s是否包含字符串substr,包含返回true
  • Split(s,sep string) []string
    将字符串s按照分隔符sep分隔为slice
  • Join(a []string,sep string) string
    字符串拼接,把slice a通过sep链接起
  • Trim(s string,cutset string) string
    在s字符串的头部和尾部去除cutset指定的字符串
  • Replace(s,old,new string,n int) string
    在s字符串中,把old字符串替换为new字符串,n表示替换的次数,小于0表示全部替换,等于0不替换
  • Repeat(s string,count int) string
    重复s字符串count次,最后返回重复的字符串
  • Index(s,substr string) int
    在字符串s中查找sep所在的位置,返回位置值,找不到返回-1。注意返回0表示首位置

strconv 字符串转换

Append 系列函数

将整数等转换为字符串后,添加到现有的字节数组中。

package main

import (
    "fmt"
    "strconv"
)

func main()  {
    str := make([]byte,10)
    str = strconv.AppendInt(str,-1,10)
    str = strconv.AppendUint(str,1,10) //无符号
    fmt.Println(string(str))
    str = strconv.AppendFloat(str,3.14159,'f',2,32)
    fmt.Println(string(str))
    str = strconv.AppendFloat(str,30.14159,'e',3,64)
    fmt.Println(string(str))
    str = strconv.AppendBool(str,true)
    fmt.Println(string(str))
    str = strconv.AppendQuote(str,"hello")
    fmt.Println(string(str))
    str = strconv.AppendQuoteRune(str,97) //字符a对应的ascii码
    fmt.Println(string(str))

}

输出:

-11
-113.14
-113.143.014e+01
-113.143.014e+01true
-113.143.014e+01true"hello"
-113.143.014e+01true"hello"'a'

注:
1、strconv.AppendInt(dst []byte,i int64,base int)的第三个参数是进制,这里写的 10 代表10进制。
2、strconv.AppendFloat(dst []byte,f float64,fmt byte,prec,bitSize int)fmt是格式标记(b、e、E、f、g、G);prec代表精度(数字部分的长度,不包括指数部分);bitSize指定浮点类型(32:float32、64:float64)。
格式标记:

// 'b' (-ddddp±ddd,二进制指数)
// 'e' (-d.dddde±dd,十进制指数)
// 'E' (-d.ddddE±dd,十进制指数)
// 'f' (-ddd.dddd,没有指数)
// 'g' ('e':大指数,'f':其它情况)
// 'G' ('E':大指数,'f':其它情况)

// 如果格式标记为 'e','E'和'f',则 prec 表示小数点后的数字位数
// 如果格式标记为 'g','G',则 prec 表示总的数字位数(整数部分+小数部分)

3、strconv.AppendQuote(dst []byte,s string) []byte 将字符串 s 转换为"双引号"引起来的字符串,并将结果追加到 dst 的尾部,返回追加后的 []byte。其中的特殊字符将被转换为"转义字符"。

Format 系列函数

把其他类型的转换为字符串。

package main

import (
    "fmt"
    "strconv"
)

func main()  {
    fmt.Println(strconv.FormatBool(true))
    fmt.Println(strconv.FormatInt(1,10))
    fmt.Println(strconv.FormatUint(1,10))
    fmt.Println(strconv.FormatFloat(3.14159,32))
}

输出:

true
1
1
3.14

Parse 系列函数

将字符串转换为 bool float int uint类型的值,err指定是否转换成功。

package main

import (
    "fmt"
    "strconv"
)

func main()  {
    fmt.Println(strconv.ParseBool("true"))
    fmt.Println(strconv.ParseInt("100",10,0))
    fmt.Println(strconv.Atoi("100")) // 通常使用这个函数,而不使用 ParseInt
    fmt.Println(strconv.ParseUint("100",0))
    fmt.Println(strconv.ParseFloat("3.14159",32))
}

输出:

true <nil>
100 <nil>
100 <nil>
100 <nil>
3.141590118408203 <nil>

注:
1、strconv.ParseInt(s string,base int,bitSize int)的第三个参数bitSize是返回结果的bit大小,也就是int8 int16 int32 int64。如果给0,则使用默认值strconv.IntSize,64位机器大小是64。

Quote 系列函数

1、strconv.Quote(s string) string将字符串 s 转换为"双引号"引起来的字符串,其中的特殊字符将被转换为"转义字符","不可显示的字符"将被转换为"转义字符"。
2、strconv.QuoteToASCII(s string) string 将字符串 s 转换为""引起来的 ASCII 字符串, "非 ASCII 字符"和"特殊字符"将被转换为"转义字符"。
3、strconv.QuoteRune(r rune) string 将 Unicode 字符转换为“单引号”引起来的字符串,“特殊字符”将被转换为“转义字符”。

package main

import (
    "fmt"
    "strconv"
)

func main()  {
    fmt.Println(strconv.Quote(`hello go 语言n`))
    fmt.Println(strconv.Quote("hello go 语言n"))
    fmt.Println(strconv.QuoteToASCII(`hello go 语言n`))
    fmt.Println(strconv.QuoteRune(97))
    fmt.Println(strconv.QuoteRuneToASCII(97))
}

输出:

"hello go 语言n"
"hello go 语言n"
"hello go u8bedu8a00n"
'a'
'a'

encoding

encoding/json

  • json.Marshal(v interface{}) ([]byte,error) 生成JSON
  • json.Unmarshal(data []byte,v interface{}) error 解析JSON到interface

解析JSON

package main

import (
    "encoding/json"
    "fmt"
)

type Employee struct {
    FirstName string `json:"firstName"`
    LastName string `json:"lastName"`
}

type EmployeeSlice struct {
    Employees []Employee `json:"employees"`
}

func main()  {
    str := `{"employees":[{"firstName":"Bill","lastName":"Gates"},{"firstName":"George","lastName":"Bush"}]}`
    var res EmployeeSlice
    json.Unmarshal([]byte(str),&res)
    fmt.Println(res)
    fmt.Println(res.Employees[0].FirstName)
}

输出:

[{Bill Gates} {George Bush}]}
Bill

生成JSON:

package main

import (
    "encoding/json"
    "fmt"
)

type Employee struct {
    FirstName string `json:"firstName"`
    LastName string `json:"lastName"`
}

type EmployeeSlice struct {
    Employees []Employee `json:"employees"`
}

func main()  {
    data := EmployeeSlice{[]Employee{
        {FirstName:"Bill",LastName:"Gates"},{FirstName:"George",LastName:"Bush"},}}
    res,_ := json.Marshal(data)
    fmt.Println(string(res))
}

输出:

{"employees":[{"firstName":"Bill","lastName":"Bush"}]}

crypto

md5

package main

import (
    "crypto/md5"
    //"io"
    "fmt"
    "encoding/hex"
)

func main(){
    h := md5.New()
    //io.WriteString(h,"123456")
    h.Write([]byte("123456"))
    cipherStr := h.Sum(nil)
    fmt.Println(cipherStr) //一个128bit的16字节byte数组
    fmt.Println(hex.EncodeToString(cipherStr)) // 输出加密结果 
}

运行输出:

[225 10 220 57 73 186 89 171 190 86 224 87 242 15 136 62]
e10adc3949ba59abbe56e057f20f883e

使用io.WriteString(h,"123456")h.Write([]byte("123456"))作用相同,可以多次Write,会把字符串追加到前一次的末尾。

除了md5,还有sha1sha256,使用方法是类似的:

//import "crypto/sha256"
h := sha256.New()
io.WriteString(h,"123456")
fmt.Printf("%x",h.Sum(nil))

//import "crypto/sha1"
h := sha1.New()
io.WriteString(h,h.Sum(nil))

base64

package main

import (
    "encoding/base64"
    "fmt"
)

// 编码
func base64Encode(str []byte) []byte {
    return []byte(base64.StdEncoding.EncodeToString(str))
}

// 解码
func base64Decode(str []byte) ([]byte,error){
    return base64.StdEncoding.DecodeString(string(str))
}

func main(){
    str := "hello"
    enc_str := base64Encode([]byte(str))
    fmt.Println(enc_str)
    fmt.Println(string(enc_str))

    dec_str,err := base64Decode(enc_str)
    if(err != nil){
        fmt.Println(err.Error())
    }

    fmt.Println(dec_str)
    fmt.Println(string(dec_str))
}

输出:

[97 71 86 115 98 71 56 61]
aGVsbG8=
[104 101 108 108 111]
hello

AES

net

net/url

net/http

net/http已经很好的支持了常见的GET、POST请求。

get请求

package main

import (
    "net/http"
    "fmt"
    "io/ioutil"
    "io"
)

func main() {
    var url string = "http://httpbin.org/get?page=1&limit=2"
    resp,err := http.Get(url)
    if (err != nil) {
        fmt.Println(err.Error())
    }

    fmt.Println(resp.Status)     //200 ok
    fmt.Println(resp.StatusCode) //200

    var bodyReader io.ReadCloser = resp.Body //返回的是io.Reader
    body,_ := ioutil.ReadAll(bodyReader)
    fmt.Println(string(body))
}

输出:

200 OK
200
{
  "args": {
    "limit": "2","page": "1"
  },"headers": {
    "Accept-Encoding": "gzip","Connection": "close","Host": "httpbin.org","User-Agent": "Go-http-client/1.1"
  },"origin": "221.217.54.202","url": "http://httpbin.org/get?page=1&limit=2"
}

post表单请求

post表单请求使用http.PostForm()。除了需要额外的参数外,其它的和get请求一样。

package main

import (
    "net/http"
    "fmt"
    "io/ioutil"
    "io"
    "net/url"
)

func main() {
    var apiURL string = "http://httpbin.org/post?page=1"
    var params url.Values = url.Values{"names": []string{"yjc","yjc1"}}
    params.Set("age","20")
    resp,err := http.PostForm(apiURL,params)
    if (err != nil) {
        fmt.Println(err.Error())
    }

    fmt.Println(resp.Status)     //200 ok
    fmt.Println(resp.StatusCode) //200

    var bodyReader io.ReadCloser = resp.Body //返回的是io.Reader
    body,_ := ioutil.ReadAll(bodyReader)
    fmt.Println(string(body))
}

输出:

200 OK
200
{
  "args": {
    "page": "1"
  },"data": "","files": {},"form": {
    "age": "20","names": [
      "yjc","yjc1"
    ]
  },"Content-Length": "27","Content-Type": "application/x-www-form-urlencoded","json": null,"url": "http://httpbin.org/post?page=1"
}

封装

package tool

import (
    "io/ioutil"
    "net/http"
    "net/url"
    "fmt"
)

// get 网络请求
func Get(apiURL string,params url.Values) (rs []byte,err error) {
    var Url *url.URL
    Url,err = url.Parse(apiURL)
    if err != nil {
        fmt.Printf("解析url错误:rn%v",err)
        return nil,err
    }
    //如果参数中有中文参数,这个方法会进行URLEncode
    Url.RawQuery = params.Encode()
    resp,err := http.Get(Url.String())
    if err != nil {
        fmt.Println("err:",err
    }
    defer resp.Body.Close()
    return ioutil.ReadAll(resp.Body)
}

// post 网络请求,params 是url.Values类型
func Post(apiURL string,err error) {
    resp,params)
    if err != nil {
        return nil,err
    }
    defer resp.Body.Close()
    return ioutil.ReadAll(resp.Body)
}

net/http/pprof

该包来做代码的性能监控。使用示例:

package main

import (
    "net/http"
    _ "net/http/pprof"
)

func main(){
    //提供给负载均衡探活以及pprof调试
    http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request) {
        w.Write([]byte("ok"))
    })

    http.ListenAndServe(":10000",nil)
}

运行之后,在浏览器打开 http://127.0.0.1:10000/debug/pprof/就能看到监控的一些信息了。生产环境一般不会按上面那么写,一般都是开个协程:

go http.ListenAndServe(":10000",nil)

如何启动 PProf 可视化界面?

需要graphviz支持,可以到 http://www.graphviz.org/download/下载,并把bin加入到环境变量。Mac可以使用brew安装。

下面以profile( CPU profile)为例:

方法一:

go tool pprof -http=:8080 http://localhost:10000/debug/pprof/profile

方法二:

go tool pprof http://localhost:10000/debug/pprof/profile

然后在交互式命令行输入web即可跳转到默认浏览器。(本机测试失败,打开了Sublime text)

参考:Golang pprof详解
https://studygolang.com/articles/14519

os

文件操作的大多数函数都是在os包里面。

目录操作:

  • func Mkdir(name string,perm FileMode) error
    创建名称为name的目录,权限设置是perm,例如0777。
  • func MkdirAll(path string,perm FileMode) error
    根据path创建多级子目录。
  • func Remove(name string) error
    删除名称为name的目录,当目录下有文件或者其他目录时会出错。
  • func RemoveAll(path string) error
    根据path删除多级子目录,如果path是单个名称,那么该目录下的子目录全部删除。

示例:

package main

import (
    "os"
    "fmt"
)

func main()  {
    os.Mkdir("tmp",0755)
    os.MkdirAll("tmp/test/test2",0755)
    err := os.Remove("tmp")
    if err != nil{
        fmt.Println(err)
    }
    os.RemoveAll("tmp")
}

运行输出:

remove tmp: The directory is not empty.

文件操作:

  • func Create(name string) (file *File,err Error)
    根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的。
  • func NewFile(fd uintptr,name string) *File
    根据文件描述符创建相应的文件,返回一个文件对象。

  • func Open(name string) (file *File,err Error)
    该方法打开一个名称为name的文件,但是是只读方式,内部实现其实调用了
    OpenFile。
  • func OpenFile(name string,flag int,perm uint32) (file *File,err Error)
    打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限
  • func (file *File) Write(b []byte) (n int,err Error)
    写入byte类型的信息到文件
  • func (file *File) WriteAt(b []byte,off int64) (n int,err Error)
    在指定位置开始写入byte类型的信息
  • func (file *File) WriteString(s string) (ret int,err Error)
    写入string信息到文件
  • func (file *File) Read(b []byte) (n int,err Error)
    读取数据到b中
  • func (file *File) ReadAt(b []byte,err Error)
    从off开始读取数据到b中
  • func Remove(name string) Error
    调用该函数就可以删除文件名为name的文件。删除文件和删除文件夹是同一个函数。

io/ioutil

ioutil包封装了一些实用的 I/O 函数,提供给外部使用的一共有1个变量,7个方法。

  • func ReadFile(filename string) ([]byte,error)
    ReadFile读取文件中的所有数据,返回读取的内容和遇到的错误。
  • func WriteFile(filename string,data []byte,perm os.FileMode) error
    WriteFile向文件写入数据,如果之前有数据则会将原来的进行清空,如果文件不存在则会以指定的权限创建该文件。

  • func ReadDir(dirname string) ([]os.FileInfo,error)
    ReadDir读取指定目录中的所有目录和文件(不包括子目录)。返回读取的文件信息列表和遇到的错误,列表是经过排序的。

  • func TempFile(dir,prefix string) (f *os.File,err error)
    TempFile在dir目录中创建一个以prefix为前缀的临时文件,并将其以读写模式打开。返回创建的文件对象和遇到的错误信息。如果dir为空,则在默认的临时目录中创建文件(参见os.TimeDir),多次调用会创建不同的临时文件,调用者可以通过f.Name()获取文件的完整路径。调用本函数所创建的临时文件,应该由调用者自己删除。
  • func TempDir(dir,prefix string) (name string,err error)
    TempDir功能是创建临时目录(其他功能和TempFile一样),返回创建的完整的目录和遇到的错误信息。

  • func ReadAll(r io.Reader) ([]byte,error)
    ReadFile读取文件中的所有数据,返回读取的数据和遇到的错误。如果读取成功,则err返回nil,而不是EOF。该方法实现了io.Reader接口的使用。

  • func NopCloser(r io.Reader) io.ReadCloser
    NopCloser将r包装为一个ReadCloser类型,但Close方法不做任何事情。

io

io包是为 IO 原语(I/O primitives)提供基本的接口。

golang的io包 - 刘地的个人空间 - 开源中国
http://www.voidcn.com/article/p-fdeyyhot-bok.html

flag

用于获取命令行参数。

示例:

package main

import (
    "flag"
    "fmt"
)

func main() {
    backup_dir := flag.String("b","/home/default_dir","backup path")
    debug_mode := flag.Bool("d",false,"debug mode")

    flag.Parse()

    fmt.Println("backup_dir: ",*backup_dir)
    fmt.Println("debug_mode: ",*debug_mode)
}

golang之flag.String - hezhixiong - 博客园
http://www.cnblogs.com/hezhixiong/p/4659477.html

sync

sync.WaitGroup

package main

import (
    "fmt"
    "time"
)

func main(){
    for i := 0; i < 100 ; i++{
        go fmt.Println(i)
    }
    time.Sleep(time.Second)
}

上面主线程为了等待goroutine都运行完毕,不得不在程序的末尾使用time.Sleep() 来睡眠一段时间,等待其他线程充分运行。但大部分时候我们都无法预知for循环内代码运行时间的长短。这时候就不能使用time.Sleep() 来完成等待操作了。

对于这种情况,go语言中有一个其他的工具sync.WaitGroup 能更加方便的帮助我们达到这个目的。WaitGroup 对象内部有一个计数器,最初从0开始,它有三个方法:Add(),Done(),Wait() 用来控制计数器的数量。Add(n) 把计数器设置为nDone() 每次把计数器-1wait() 会阻塞代码的运行,直到计数器地值减为0

使用WaitGroup 将上述代码可以修改为:

func main() {
    wg := sync.WaitGroup{}
    wg.Add(100)
    for i := 0; i < 100; i++ {
        go func(i int) {
            fmt.Println(i)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

详见:Golang sync.WaitGroup的用法
https://studygolang.com/articles/12972?fr=sidebar

runtime

runtime/debug

用于:

  • 强制进行垃圾回收
  • 设置垃圾回收的目标百分比
  • 设置被单个go协程调用栈可使用的内存最大值
  • 设置go程序可以使用的最大操作系统线程数
  • 设置程序请求运行是只触发panic,而不崩溃
  • 垃圾收集信息的写入stats中
  • 将内存分配堆和其中对象的描述写入文件中
  • 获取go协程调用栈踪迹
  • 将堆栈踪迹打印到标准错误

详见:go-runtime/debug
https://www.jianshu.com/p/0b3d11f7af57

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读