golang小程序试验(三)

前端之家收集整理的这篇文章主要介绍了golang小程序试验(三)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1. golang的log模块

golang的log模块可以很方便的创建自己的日志记录,包括日志文件路径,日志格式等都可以自己定义。先来看一个程序:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "log"
  6. "os"
  7. )
  8.  
  9. func main() {
  10. logfile,err := os.OpenFile("d:\\test.log",os.O_RDWR|os.O_CREATE,0)
  11. if err != nil {
  12. fmt.Printf("%s\r\n",err.Error())
  13. os.Exit(-1)
  14. }
  15. defer logfile.Close()
  16. logger := log.New(logfile,"\r\n",log.Ldate|log.Ltime|log.Llongfile)
  17. logger.Println("hello")
  18. logger.Println("oh....")
  19. logger.Fatal("test")
  20. logger.Fatal("test2")
  21. }

首先创建一个log文件,然后利用log.New()创建一个Logger对象,并定义log文件内容的格式,New()定义如下:

  1. func New(out io.Writer,prefix string,flag int) *Logger
Ldate、Ltime等被定义为常量:
  1. const (
  2. // Bits or'ed together to control what's printed. There is no control over the
  3. // order they appear (the order listed here) or the format they present (as
  4. // described in the comments). A colon appears after these items:
  5. // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
  6. Ldate = 1 << iota // the date: 2009/01/23
  7. Ltime // the time: 01:23:23
  8. Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
  9. Llongfile // full file name and line number: /a/b/c/d.go:23
  10. Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
  11. LstdFlags = Ldate | Ltime // initial values for the standard logger
  12. )

通过Print()、Println()、Printf()等函数可以向log文件中写入log记录了。然后调用Fatal()等函数记录最后一条log,并退出(Fatal()中包含了调用os.Exit(1))。

Logger给出的结论是:A Logger can be used simultaneously from multiple goroutines; it guarantees to serialize access to the Writer. 也就是说是线程安全的。

2. golang的archive/zip模块

此模块比较简单,直接用一个程序说明:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "os"
  6. "log"
  7. "archive/zip"
  8. "io"
  9. )
  10.  
  11. const (
  12. LOGFILEPATH = "d:\\zip.log"
  13. )
  14.  
  15. func main(){
  16. logfile,err := os.OpenFile(LOGFILEPATH,os.O_CREATE|os.O_RDWR,0);
  17. if err!=nil {
  18. fmt.Println(err.Error());
  19. return;
  20. }
  21. defer logfile.Close();
  22. logger := log.New(logfile,log.Ldate|log.Ltime|log.Llongfile);
  23. if logger==nil {
  24. fmt.Println("logger init error");
  25. }
  26. r,err := zip.OpenReader("d:\\新建文本文档.zip");
  27. if err!=nil {
  28. logger.Fatal(err);
  29. }
  30. defer r.Close();
  31. for _,f := range r.File {
  32. fmt.Println("FileName : ",f.Name);
  33. rc,err := f.Open();
  34. if err!=nil {
  35. logger.Fatal(err);
  36. }
  37. _,err = io.CopyN(os.Stdout,rc,68); //打印文件内容
  38. if err!=nil {
  39. if err!=io.EOF {
  40. logger.Fatal(err);
  41. }
  42. }
  43. }
  44. }

3. panic与recover

第一篇文章已经介绍过,这里再来一个例子:

  1. package main
  2. import "fmt"
  3.  
  4. func main() {
  5. T()
  6. //recover执行后,这里会继续执行
  7. fmt.Println("after recover.")
  8. }
  9.  
  10. func T() {
  11. defer func() {
  12. fmt.Println("defer func is run")
  13. //recover只能在defer()函数中执行
  14. r := recover()
  15. if r != nil {
  16. fmt.Println("recover: ",r)
  17. }
  18. }()
  19. fmt.Println("body")
  20. //panic中的文本会传给recover
  21. panic("panic is run")
  22. fmt.Println("body 2")
  23. }

4. golang的base64加解密

  1. package main
  2.  
  3. import (
  4. "encoding/base64"
  5. "fmt"
  6. )
  7.  
  8. const (
  9. base64Table = "123QRSTUabcdVWXYZHijKLAWDCABDstEFGuvwxyzGHIJklmnopqr234560178912"
  10. )
  11.  
  12. var coder = base64.NewEncoding(base64Table)
  13.  
  14. func base64Encode(src []byte) []byte {
  15. return []byte(coder.EncodeToString(src))
  16. }
  17.  
  18. func base64Decode(src []byte) ([]byte,error) {
  19. return coder.DecodeString(string(src))
  20. }
  21.  
  22. func main() {
  23. // encode
  24. hello := "hello world"
  25. debyte := base64Encode([]byte(hello))
  26.  
  27. // decode
  28. enbyte,err := base64Decode(debyte)
  29. if err != nil {
  30. fmt.Println(err.Error())
  31. }
  32.  
  33. if hello != string(enbyte) {
  34. fmt.Println("hello is not equal to enbyte")
  35. }
  36.  
  37. fmt.Println(string(enbyte))
  38. }

5. golang的time包

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "time"
  6. )
  7.  
  8. func main() {
  9. //时间戳
  10. t := time.Now().Unix()
  11. fmt.Println(t)
  12.  
  13. //时间戳到具体显示的转化
  14. fmt.Println(time.Unix(t,0).String())
  15.  
  16. //带纳秒的时间戳
  17. t = time.Now().UnixNano()
  18. fmt.Println(t)
  19. fmt.Println("------------------")
  20.  
  21. //基本格式化的时间表示
  22. fmt.Println(time.Now().String())
  23.  
  24. fmt.Println(time.Now().Format("2006year 01month 02day"))
  25.  
  26. }
输出今天是星期几:
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "time"
  6. )
  7.  
  8. func main() {
  9. //时间戳
  10. t := time.Now()
  11. fmt.Println(t.Weekday().String())
  12.  
  13. }

6. golang反射举例

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "reflect"
  6. )
  7.  
  8. type MyStruct struct {
  9. name string
  10. }
  11.  
  12. func (this *MyStruct) GetName() string {
  13. return this.name
  14. }
  15.  
  16. func main() {
  17. fmt.Println("--------------")
  18. var a MyStruct
  19. b := new(MyStruct)
  20. fmt.Println(reflect.ValueOf(a))
  21. fmt.Println(reflect.ValueOf(b))
  22.  
  23. fmt.Println("--------------")
  24. a.name = "abc"
  25. b.name = "def"
  26. val := reflect.ValueOf(a).FieldByName("name")
  27. fmt.Println(val)
  28.  
  29. //val2 := reflect.ValueOf(b).FieldByName("name")
  30. //panic: reflect: call of reflect.Value.FieldByName on ptr Value
  31. //b是一个指针,指针的ValueOf返回的是指针的Type,它是没有Field的,所以也就不能使用FieldByName
  32.  
  33. fmt.Println("--------------")
  34. fmt.Println(reflect.ValueOf(a).FieldByName("name").CanSet())
  35. fmt.Println(reflect.ValueOf(&(a.name)).Elem().CanSet())
  36.  
  37. fmt.Println("--------------")
  38. var c string = "xyz"
  39. p := reflect.ValueOf(&c)
  40. fmt.Println(p.CanSet()) //false
  41. fmt.Println(p.Elem().CanSet()) //true
  42. p.Elem().SetString("newName")
  43. fmt.Println(c)
  44. }

执行结果:

  1. --------------
  2. <main.MyStruct Value>
  3. <*main.MyStruct Value>
  4. --------------
  5. abc
  6. --------------
  7. false
  8. true
  9. --------------
  10. false
  11. true
  12. newName

a和b的ValueOf()返回的是不一样的值,因为b是用new()创建的,是个指针。

当前面的CanSet是一个指针的时候(p)它是不可寻址的,但是当是p.Elem()(实际上就是*p),它就是可以寻址的。

猜你在找的Go相关文章