go编程之常见工具函数

Posted 朝十晚八

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go编程之常见工具函数相关的知识,希望对你有一定的参考价值。

1、时间格式化

  基于模式的布局进行时间格式化和解析

 1 package main
 2 
 3 import "fmt"
 4 import "time"
 5 
 6 func main() {
 7     p := fmt.Println
 8 
 9     t := time.Now()
10     p(t.Format(time.RFC3339))
11 
12     t1, e := time.Parse(
13         time.RFC3339,
14         "2012-11-01T22:08:41+00:00")
15     p(t1)
16 
17     p(t.Format("3:04PM"))
18     p(t.Format("Mon Jan _2 15:04:05 2006"))
19     p(t.Format("2006-01-02T15:04:05.999999-07:00"))
20     form := "3 04 PM"
21     t2, e := time.Parse(form, "8 41 PM")
22     p(t2)
23 
24     fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
25         t.Year(), t.Month(), t.Day(),
26         t.Hour(), t.Minute(), t.Second())
27 
28     ansic := "Mon Jan _2 15:04:05 2006"
29     _, e = time.Parse(ansic, "8:41PM")
30     p(e)
31 }

  执行上面代码,将得到以下输出结果

1 2017-03-23T11:41:52+08:00
2 2012-11-01 22:08:41 +0000 +0000
3 11:41AM
4 Thu Mar 23 11:41:52 2017
5 2017-03-23T11:41:52.246508+08:00
6 0000-01-01 20:41:00 +0000 UTC
7 2017-03-23T11:41:52-00:00
8 parsing time "8:41PM" as "Mon Jan _2 15:04:05 2006": cannot parse "8:41PM" as "Mon"

2、字符串格式化

 1 package main
 2 
 3 import "fmt"
 4 import "os"
 5 
 6 type point struct {
 7     x, y int
 8 }
 9 
10 func main() {
11     p := point{1, 2}
12     fmt.Printf("%v\n", p)
13 
14     fmt.Printf("%+v\n", p)
15 
16     fmt.Printf("%#v\n", p)
17 
18     fmt.Printf("%T\n", p)
19 
20     fmt.Printf("%t\n", true)
21 
22     fmt.Printf("%d\n", 123)
23 
24     fmt.Printf("%b\n", 14)
25 
26     fmt.Printf("%c\n", 33)
27 
28     fmt.Printf("%x\n", 456)
29 
30     fmt.Printf("%f\n", 78.9)
31 
32     fmt.Printf("%e\n", 123400000.0)
33     fmt.Printf("%E\n", 123400000.0)
34 
35     fmt.Printf("%s\n", "\"string\"")
36 
37     fmt.Printf("%q\n", "\"string\"")
38 
39     fmt.Printf("%x\n", "hex this")
40 
41     fmt.Printf("%p\n", &p)
42 
43     fmt.Printf("|%6d|%6d|\n", 12, 345)
44 
45     fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
46 
47     fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)
48 
49     fmt.Printf("|%6s|%6s|\n", "foo", "b")
50 
51     fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
52 
53     s := fmt.Sprintf("a %s", "string")
54     fmt.Println(s)
55 
56     fmt.Fprintf(os.Stderr, "an %s\n", "error")
57 }
 1 {1 2}
 2 {x:1 y:2}
 3 main.point{x:1, y:2}
 4 main.point
 5 true
 6 123
 7 1110
 8 !
 9 1c8
10 78.900000
11 1.234000e+08
12 1.234000E+08
13 "string"
14 "\"string\""
15 6865782074686973
16 0xc042004280
17 |    12|   345|
18 |  1.20|  3.45|
19 |1.20  |3.45  |
20 |   foo|     b|
21 |foo   |b     |
22 a string
23 an error

3、正则表达式

 1 package main
 2 
 3 import "bytes"
 4 import "fmt"
 5 import "regexp"
 6 
 7 func main() {
 8 
 9     // This tests whether a pattern matches a string.
10     match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
11     fmt.Println(match)
12 
13     // Above we used a string pattern directly, but for
14     // other regexp tasks you‘ll need to `Compile` an
15     // optimized `Regexp` struct.
16     r, _ := regexp.Compile("p([a-z]+)ch")
17 
18     // Many methods are available on these structs. Here‘s
19     // a match test like we saw earlier.
20     fmt.Println(r.MatchString("peach"))
21 
22     // This finds the match for the regexp.
23     fmt.Println(r.FindString("peach punch"))
24 
25     // This also finds the first match but returns the
26     // start and end indexes for the match instead of the
27     // matching text.
28     fmt.Println(r.FindStringIndex("peach punch"))
29 
30     // The `Submatch` variants include information about
31     // both the whole-pattern matches and the submatches
32     // within those matches. For example this will return
33     // information for both `p([a-z]+)ch` and `([a-z]+)`.
34     fmt.Println(r.FindStringSubmatch("peach punch"))
35 
36     // Similarly this will return information about the
37     // indexes of matches and submatches.
38     fmt.Println(r.FindStringSubmatchIndex("peach punch"))
39 
40     // The `All` variants of these functions apply to all
41     // matches in the input, not just the first. For
42     // example to find all matches for a regexp.
43     fmt.Println(r.FindAllString("peach punch pinch", -1))
44 
45     // These `All` variants are available for the other
46     // functions we saw above as well.
47     fmt.Println(r.FindAllStringSubmatchIndex(
48         "peach punch pinch", -1))
49 
50     // Providing a non-negative integer as the second
51     // argument to these functions will limit the number
52     // of matches.
53     fmt.Println(r.FindAllString("peach punch pinch", 2))
54 
55     // Our examples above had string arguments and used
56     // names like `MatchString`. We can also provide
57     // `[]byte` arguments and drop `String` from the
58     // function name.
59     fmt.Println(r.Match([]byte("peach")))
60 
61     // When creating constants with regular expressions
62     // you can use the `MustCompile` variation of
63     // `Compile`. A plain `Compile` won‘t work for
64     // constants because it has 2 return values.
65     r = regexp.MustCompile("p([a-z]+)ch")
66     fmt.Println(r)
67 
68     // The `regexp` package can also be used to replace
69     // subsets of strings with other values.
70     fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
71 
72     // The `Func` variant allows you to transform matched
73     // text with a given function.
74     in := []byte("a peach")
75     out := r.ReplaceAllFunc(in, bytes.ToUpper)
76     fmt.Println(string(out))
77 }

  执行上面代码,将得到以下输出结果

 1 true
 2 true
 3 peach
 4 [0 5]
 5 [peach ea]
 6 [0 5 1 3]
 7 [peach punch pinch]
 8 [[0 5 1 3] [6 11 7 9] [12 17 13 15]]
 9 [peach punch]
10 true
11 p([a-z]+)ch
12 a <fruit>
13 a PEACH

4、Json

  1 package main
  2 
  3 import "encoding/json"
  4 import "fmt"
  5 import "os"
  6 
  7 // We‘ll use these two structs to demonstrate encoding and
  8 // decoding of custom types below.
  9 type Response1 struct {
 10     Page   int
 11     Fruits []string
 12 }
 13 type Response2 struct {
 14     Page   int      `json:"page"`
 15     Fruits []string `json:"fruits"`
 16 }
 17 
 18 func main() {
 19 
 20     // First we‘ll look at encoding basic data types to
 21     // JSON strings. Here are some examples for atomic
 22     // values.
 23     bolB, _ := json.Marshal(true)
 24     fmt.Println(string(bolB))
 25 
 26     intB, _ := json.Marshal(1)
 27     fmt.Println(string(intB))
 28 
 29     fltB, _ := json.Marshal(2.34)
 30     fmt.Println(string(fltB))
 31 
 32     strB, _ := json.Marshal("gopher")
 33     fmt.Println(string(strB))
 34 
 35     // And here are some for slices and maps, which encode
 36     // to JSON arrays and objects as you‘d expect.
 37     slcD := []string{"apple", "peach", "pear"}
 38     slcB, _ := json.Marshal(slcD)
 39     fmt.Println(string(slcB))
 40 
 41     mapD := map[string]int{"apple": 5, "lettuce": 7}
 42     mapB, _ := json.Marshal(mapD)
 43     fmt.Println(string(mapB))
 44 
 45     // The JSON package can automatically encode your
 46     // custom data types. It will only include exported
 47     // fields in the encoded output and will by default
 48     // use those names as the JSON keys.
 49     res1D := &Response1{
 50         Page:   1,
 51         Fruits: []string{"apple", "peach", "pear"}}
 52     res1B, _ := json.Marshal(res1D)
 53     fmt.Println(string(res1B))
 54 
 55     // You can use tags on struct field declarations
 56     // to customize the encoded JSON key names. Check the
 57     // definition of `Response2` above to see an example
 58     // of such tags.
 59     res2D := &Response2{
 60         Page:   1,
 61         Fruits: []string{"apple", "peach", "pear"}}
 62     res2B, _ := json.Marshal(res2D)
 63     fmt.Println(string(res2B))
 64 
 65     // Now let‘s look at decoding JSON data into Go
 66     // values. Here‘s an example for a generic data
 67     // structure.
 68     byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
 69 
 70     // We need to provide a variable where the JSON
 71     // package can put the decoded data. This
 72     // `map[string]interface{}` will hold a map of strings
 73     // to arbitrary data types.
 74     var dat map[string]interface{}
 75 
 76     // Here‘s the actual decoding, and a check for
 77     // associated errors.
 78     if err := json.Unmarshal(byt, &dat); err != nil {
 79         panic(err)
 80     }
 81     fmt.Println(dat)
 82 
 83     // In order to use the values in the decoded map,
 84     // we‘ll need to cast them to their appropriate type.
 85     // For example here we cast the value in `num` to
 86     // the expected `float64` type.
 87     num := dat["num"].(float64)
 88     fmt.Println(num)
 89 
 90     // Accessing nested data requires a series of
 91     // casts.
 92     strs := dat["strs"].([]interface{})
 93     str1 := strs[0].(string)
 94     fmt.Println(str1)
 95 
 96     // We can also decode JSON into custom data types.
 97     // This has the advantages of adding additional
 98     // type-safety to our programs and eliminating the
 99     // need for type assertions when accessing the decoded
100     // data.
101     str := `{"page": 1, "fruits": ["apple", "peach"]}`
102     res := Response2{}
103     json.Unmarshal([]byte(str), &res)
104     fmt.Println(res)
105     fmt.Println(res.Fruits[0])
106 
107     // In the examples above we always used bytes and
108     // strings as intermediates between the data and
109     // JSON representation on standard out. We can also
110     // stream JSON encodings directly to `os.Writer`s like
111     // `os.Stdout` or even HTTP response bodies.
112     enc := json.NewEncoder(os.Stdout)
113     d := map[string]int{"apple": 5, "lettuce": 7}
114     enc.Encode(d)
115 }

  执行上面代码,将得到以下输出结果

 1 true
 2 1
 3 2.34
 4 "gopher"
 5 ["apple","peach","pear"]
 6 {"apple":5,"lettuce":7}
 7 {"Page":1,"Fruits":["apple","peach","pear"]}
 8 {"page":1,"fruits":["apple","peach","pear"]}
 9 map[num:6.13 strs:[a b]]
10 6.13
11 a
12 {1 [apple peach]}
13 apple
14 {"apple":5,"lettuce":7}

5、数字解析

 1 package main
 2 
 3 // The built-in package `strconv` provides the number
 4 // parsing.
 5 import "strconv"
 6 import "fmt"
 7 
 8 func main() {
 9 
10     // With `ParseFloat`, this `64` tells how many bits of
11     // precision to parse.
12     f, _ := strconv.ParseFloat("1.234", 64)
13     fmt.Println(f)
14 
15     // For `ParseInt`, the `0` means infer the base from
16     // the string. `64` requires that the result fit in 64
17     // bits.
18     i, _ := strconv.ParseInt("123", 0, 64)
19     fmt.Println(i)
20 
21     // `ParseInt` will recognize hex-formatted numbers.
22     d, _ := strconv.ParseInt("0x1c8", 0, 64)
23     fmt.Println(d)
24 
25     // A `ParseUint` is also available.
26     u, _ := strconv.ParseUint("789", 0, 64)
27     fmt.Println(u)
28 
29     // `Atoi` is a convenience function for basic base-10
30     // `int` parsing.
31     k, _ := strconv.Atoi("135")
32     fmt.Println(k)
33 
34     // Parse functions return an error on bad input.
35     _, e := strconv.Atoi("wat")
36     fmt.Println(e)
37 }

  执行上面代码,将得到以下输出结果

1 1.234
2 123
3 456
4 789
5 135
6 strconv.ParseInt: parsing "wat": invalid syntax

6、Url解析

 1 package main
 2 
 3 import "fmt"
 4 import "net"
 5 import "net/url"
 6 
 7 func main() {
 8 
 9     s := "postgres://user:[email protected]:5432/path?k=v#f"
10 
11     u, err := url.Parse(s)
12     if err != nil {
13         panic(err)
14     }
15 
16     fmt.Println(u.Scheme)
17 
18     fmt.Println(u.User)
19     fmt.Println(u.User.Username())
20     p, _ := u.User.Password()
21     fmt.Println(p)
22 
23     fmt.Println(u.Host)
24     host, port, _ := net.SplitHostPort(u.Host)
25     fmt.Println(host)
26     fmt.Println(port)
27 
28     fmt.Println(u.Path)
29     fmt.Println(u.Fragment)
30 
31     fmt.Println(u.RawQuery)
32     m, _ := url.ParseQuery(u.RawQuery)
33     fmt.Println(m)
34     fmt.Println(m["k"][0])
35 }

  执行上面代码,将得到以下输出结果

 1 postgres
 2 user:pass
 3 user
 4 pass
 5 host.com:5432
 6 host.com
 7 5432
 8 /path
 9 f
10 k=v
11 map[k:[v]]
12 v

7、SHA1哈希

package main

// Go implements several hash functions in various
// `crypto/*` packages.
import "crypto/sha1"
import "fmt"

func main() {
    s := "sha1 this string"//原始字符串

    h := sha1.New()//加密对象

    h.Write([]byte(s))//将原始字符串转换成字节切片传给加密对象

    bs := h.Sum(nil)//哈希结果追加和片段  可以不需要

    fmt.Println(s)//打印原始字符串
    fmt.Printf("%x\n", bs)//输出哈希结果
}

  执行上面代码,将得到以下输出结果

1 sha1 this string
2 cf23df2207d99a74fbe169e3eba035e633b65d94

8、Base64编码

  Go提供对base64编码/解码的内置支持。导入带有b64名称的encoding/base64软件包,而不是默认的base64。它会节省我们一些空间。编码器需要一个[]byte,所以将字符串转换为该类型。

 1 import b64 "encoding/base64"
 2 import "fmt"
 3 
 4 func main() {
 5     data := "abc123!?$*&()‘[email protected]~"
 6 
 7     sEnc := b64.StdEncoding.EncodeToString([]byte(data))
 8     fmt.Println(sEnc)
 9 
10 
11     sDec, _ := b64.StdEncoding.DecodeString(sEnc)
12     fmt.Println(string(sDec))
13     fmt.Println()
14 
15     uEnc := b64.URLEncoding.EncodeToString([]byte(data))
16     fmt.Println(uEnc)
17     uDec, _ := b64.URLEncoding.DecodeString(uEnc)
18     fmt.Println(string(uDec))
19 }

  执行上面代码,将得到以下输出结果

1 YWJjMTIzIT8kKiYoKSctPUB+
2 abc123!?$*&()[email protected]~
3 
4 YWJjMTIzIT8kKiYoKSctPUB-
5 abc123!?$*&()[email protected]~

9、文件读写

  读取和写入文件是许多Go程序所需的基本任务。

1、读取文件

 1 package main
 2 
 3 import (
 4     "bufio"
 5     "fmt"
 6     "io"
 7     "io/ioutil"
 8     "os"
 9 )
10 //检查error状态 如果包含错误信息  则使用panic中断
11 func check(e error) {
12     if e != nil {
13         panic(e)
14     }
15 }
16 
17 func main() {
18 
19     dat, err := ioutil.ReadFile("/tmp/dat")//直接读取文件内容到内存
20     check(err)
21     fmt.Print(string(dat))
22 
23     //使用os.Open打开文件 以获取文件的更多操作
24     f, err := os.Open("/tmp/dat")
25     check(err)
26 
27     b1 := make([]byte, 5)
28     n1, err := f.Read(b1)//读取5个字节
29     check(err)
30     fmt.Printf("%d bytes: %s\n", n1, string(b1))
31 
32     o2, err := f.Seek(6, 0)//定位到文件开头6个字符后
33     check(err)
34     b2 := make([]byte, 2)
35     n2, err := f.Read(b2)//读取2个字节
36     check(err)
37     fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2))
38 
39     o3, err := f.Seek(6, 0)
40     check(err)
41     b3 := make([]byte, 2)
42     n3, err := io.ReadAtLeast(f, b3, 2)//使用io对象读取
43     check(err)
44     fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))
45 
46     _, err = f.Seek(0, 0)//定位到文件开始位置
47     check(err)
48 
49     r4 := bufio.NewReader(f)//bufio先读取到缓存
50     b4, err := r4.Peek(5)//然后从缓存中拿字节  比较高效
51     check(err)
52     fmt.Printf("5 bytes: %s\n", string(b4))
53 
54     f.Close()
55 }

  执行上面代码,将得到以下输出结果

1 abcdfawef!@
2 cawfe
3 awefawef
4 
5 awefaf
6 5 bytes: abcdf
7 2 bytes @ 6: we
8 2 bytes @ 6: we
9 5 bytes: abcdf

2、文件写入

 1 package main
 2 
 3 import (
 4     "bufio"
 5     "fmt"
 6     "io/ioutil"
 7     "os"
 8 )
 9 
10 func check(e error) {
11     if e != nil {
12         panic(e)
13     }
14 }
15 
16 func main() {
17     d1 := []byte("hello\ngo\n")
18     err := ioutil.WriteFile("dat1.txt", d1, 0644)
19     check(err)
20 
21     f, err := os.Create("dat2.txt")
22     check(err)
23 
24     defer f.Close()//延迟关闭文件操作(f超出作用域)
25 
26     d2 := []byte{115, 111, 109, 101, 10}
27     n2, err := f.Write(d2)
28     check(err)
29     fmt.Printf("wrote %d bytes\n", n2)
30 
31     n3, err := f.WriteString("writes\n")
32     fmt.Printf("wrote %d bytes\n", n3)
33 
34     f.Sync()
35 
36     w := bufio.NewWriter(f)
37     n4, err := w.WriteString("buffered\n")
38     fmt.Printf("wrote %d bytes\n", n4)
39 
40     w.Flush()
41 }

10、行过滤器

 1 package main
 2 
 3 import (
 4     "bufio"//读写
 5     "fmt"//格式化输出
 6     "os"//操作系统
 7     "strings"//字符串
 8 )
 9 
10 func main() {
11     scanner := bufio.NewScanner(os.Stdin)//扫描标准输入
12 
13     for scanner.Scan() {
14         ucl := strings.ToUpper(scanner.Text())//
15         fmt.Println(ucl)
16     }
17 
18     if err := scanner.Err(); err != nil {//发送错误  退出
19         fmt.Fprintln(os.Stderr, "error:", err)
20         os.Exit(1)
21     }
22 }

11、环境变量

  通过os包获取和设置环境变量

 1 package main
 2 
 3 import "os"
 4 import "strings"
 5 import "fmt"
 6 
 7 func main() {
 8 
 9     // To set a key/value pair, use `os.Setenv`. To get a
10     // value for a key, use `os.Getenv`. This will return
11     // an empty string if the key isn‘t present in the
12     // environment.
13     os.Setenv("FOO", "1")
14     fmt.Println("FOO:", os.Getenv("FOO"))
15     fmt.Println("BAR:", os.Getenv("BAR"))
16 
17     // Use `os.Environ` to list all key/value pairs in the
18     // environment. This returns a slice of strings in the
19     // form `KEY=value`. You can `strings.Split` them to
20     // get the key and value. Here we print all the keys.
21     fmt.Println()
22     for _, e := range os.Environ() {
23         pair := strings.Split(e, "=")
24         fmt.Println(pair[0])
25     }
26 }

12、信号

  信号通知通过在通道上发送os.Signal值来工作。

 1 package main
 2 
 3 import "fmt"
 4 import "os"
 5 import "os/signal"
 6 import "syscall"
 7 
 8 func main() {
 9 
10     sigs := make(chan os.Signal, 1)//信号通道
11     done := make(chan bool, 1)
12 
13     signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
14 
15     go func() {
16         sig := <-sigs//等待信号
17         fmt.Println()
18         fmt.Println(sig)
19         done <- true//发送给done通道
20     }()
21 
22     fmt.Println("awaiting signal")
23     <-done//收到匿名函数发送的true值后  退出程序
24     fmt.Println("exiting")
25 }

  执行上面代码,将得到以下输出结果

1 awaiting signal
2 [Ctl+C]
3 interrupt
4 exiting

 

以上是关于go编程之常见工具函数的主要内容,如果未能解决你的问题,请参考以下文章

Go基础学习四之函数function结构struct方法method

Go语言设计模式之函数式选项模式

面向面试编程代码片段之GC

Go十大常见错误第8篇:并发编程中Context使用常见错误

Go编程模式 - 5.函数式选项

Go语言中常见的几种反模式[译]