首页 > 代码库 > go编程之常见工具函数

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:002 2012-11-01 22:08:41 +0000 +00003 11:41AM4 Thu Mar 23 11:41:52 20175 2017-03-23T11:41:52.246508+08:006 0000-01-01 20:41:00 +0000 UTC7 2017-03-23T11:41:52-00:008 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 1c810 78.90000011 1.234000e+0812 1.234000E+0813 "string"14 "\"string\""15 686578207468697316 0xc04200428017 |    12|   345|18 |  1.20|  3.45|19 |1.20  |3.45  |20 |   foo|     b|21 |foo   |b     |22 a string23 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 for14     // other regexp tasks you‘ll need to `Compile` an15     // optimized `Regexp` struct.16     r, _ := regexp.Compile("p([a-z]+)ch")17 18     // Many methods are available on these structs. Here‘s19     // 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 the26     // start and end indexes for the match instead of the27     // matching text.28     fmt.Println(r.FindStringIndex("peach punch"))29 30     // The `Submatch` variants include information about31     // both the whole-pattern matches and the submatches32     // within those matches. For example this will return33     // 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 the37     // indexes of matches and submatches.38     fmt.Println(r.FindStringSubmatchIndex("peach punch"))39 40     // The `All` variants of these functions apply to all41     // matches in the input, not just the first. For42     // 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 other46     // 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 second51     // argument to these functions will limit the number52     // of matches.53     fmt.Println(r.FindAllString("peach punch pinch", 2))54 55     // Our examples above had string arguments and used56     // names like `MatchString`. We can also provide57     // `[]byte` arguments and drop `String` from the58     // function name.59     fmt.Println(r.Match([]byte("peach")))60 61     // When creating constants with regular expressions62     // you can use the `MustCompile` variation of63     // `Compile`. A plain `Compile` won‘t work for64     // 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 replace69     // subsets of strings with other values.70     fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))71 72     // The `Func` variant allows you to transform matched73     // 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 true11 p([a-z]+)ch12 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 decoded100     // 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 and108     // strings as intermediates between the data and109     // JSON representation on standard out. We can also110     // stream JSON encodings directly to `os.Writer`s like111     // `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.1311 a12 {1 [apple peach]}13 apple14 {"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 of11     // precision to parse.12     f, _ := strconv.ParseFloat("1.234", 64)13     fmt.Println(f)14 15     // For `ParseInt`, the `0` means infer the base from16     // the string. `64` requires that the result fit in 6417     // 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-1030     // `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.2342 1233 4564 7895 1356 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:pass@host.com: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 f10 k=v11 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 string2 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!?$*&()‘-=@~" 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!?$*&()-=@~3 4 YWJjMTIzIT8kKiYoKSctPUB-5 abc123!?$*&()-=@~

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 cawfe3 awefawef4 5 awefaf6 5 bytes: abcdf7 2 bytes @ 6: we8 2 bytes @ 6: we9 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 a10     // value for a key, use `os.Getenv`. This will return11     // an empty string if the key isn‘t present in the12     // 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 the18     // environment. This returns a slice of strings in the19     // form `KEY=value`. You can `strings.Split` them to20     // 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 signal2 [Ctl+C]3 interrupt4 exiting

 

go编程之常见工具函数