golang的log模块可以很方便的创建自己的日志记录,包括日志文件路径,日志格式等都可以自己定义。先来看一个程序:
package mainimport ( "fmt" "log" "os")func main() { logfile,err := os.Openfile("d:\test.log",os.O_RDWR|os.O_CREATE,0) if err != nil { fmt.Printf("%s\r\n",err.Error()) os.Exit(-1) } defer logfile.Close() logger := log.New(logfile,"\r\n",log.Ldate|log.Ltime|log.Llongfile) logger.Println("hello") logger.Println("oh....") logger.Fatal("test") logger.Fatal("test2")}
首先创建一个log文件,然后利用log.New()创建一个Logger对象,并定义log文件内容的格式,New()定义如下:
func New(out io.Writer,prefix string,flag int) *LoggerLdate、Ltime等被定义为常量:
const ( // Bits or'ed together to control what's printed. There is no control over the // order they appear (the order Listed here) or the format they present (as // described in the comments). A colon appears after these items: // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message Ldate = 1 << iota // the date: 2009/01/23 Ltime // the time: 01:23:23 Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. Llongfile // full file name and line number: /a/b/c/d.go:23 Lshortfile // final file name element and line number: d.go:23. overrIDes Llongfile LstdFlags = Ldate | Ltime // initial values for the standard logger)
通过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. 也就是说是线程安全的。
@H_404_20@ 2. golang的archive/zip模块此模块比较简单,直接用一个程序说明:
package mainimport ( "fmt" "os" "log" "archive/zip" "io")const ( LOGfilePATH = "d:\zip.log")func main(){ logfile,err := os.Openfile(LOGfilePATH,os.O_CREATE|os.O_RDWR,0); if err!=nil { fmt.Println(err.Error()); return; } defer logfile.Close(); logger := log.New(logfile,log.Ldate|log.Ltime|log.Llongfile); if logger==nil { fmt.Println("logger init error"); } r,err := zip.OpenReader("d:\新建文本文档.zip"); if err!=nil { logger.Fatal(err); } defer r.Close(); for _,f := range r.file { fmt.Println("filename : ",f.name); rc,err := f.open(); if err!=nil { logger.Fatal(err); } _,err = io.copyN(os.Stdout,rc,68); //打印文件内容 if err!=nil { if err!=io.EOF { logger.Fatal(err); } } }}3. panic与recover
第一篇文章已经介绍过,这里再来一个例子:
package mainimport "fmt"func main() { T() //recover执行后,这里会继续执行 fmt.Println("after recover.")}func T() { defer func() { fmt.Println("defer func is run") //recover只能在defer()函数中执行 r := recover() if r != nil { fmt.Println("recover: ",r) } }() fmt.Println("body") //panic中的文本会传给recover panic("panic is run") fmt.Println("body 2")}4. golang的base64加解密
package mainimport ( "enCoding/base64" "fmt")const ( base64table = "123QRSTUabcdVWXYZHijKLAWDCABDstEFGuvwxyzGHIJklmnopqr234560178912")var coder = base64.NewEnCoding(base64table)func base64Encode(src []byte) []byte { return []byte(coder.EncodetoString(src))}func base64Decode(src []byte) ([]byte,error) { return coder.DecodeString(string(src))}func main() { // encode hello := "hello world" debyte := base64Encode([]byte(hello)) // decode enbyte,err := base64Decode(debyte) if err != nil { fmt.Println(err.Error()) } if hello != string(enbyte) { fmt.Println("hello is not equal to enbyte") } fmt.Println(string(enbyte))}5. golang的time包
package mainimport ( "fmt" "time")func main() { //时间戳 t := time.Now().Unix() fmt.Println(t) //时间戳到具体显示的转化 fmt.Println(time.Unix(t,0).String()) //带纳秒的时间戳 t = time.Now().UnixNano() fmt.Println(t) fmt.Println("------------------") //基本格式化的时间表示 fmt.Println(time.Now().String()) fmt.Println(time.Now().Format("2006year 01month 02day"))}输出今天是星期几:
package mainimport ("fmt""time")func main() {//时间戳t := time.Now()fmt.Println(t.Weekday().String())}6. golang反射举例
package mainimport ( "fmt" "reflect")type MyStruct struct { name string}func (this *MyStruct) Getname() string { return this.name}func main() { fmt.Println("--------------") var a MyStruct b := new(MyStruct) fmt.Println(reflect.ValueOf(a)) fmt.Println(reflect.ValueOf(b)) fmt.Println("--------------") a.name = "abc" b.name = "def" val := reflect.ValueOf(a).FIEldByname("name") fmt.Println(val) //val2 := reflect.ValueOf(b).FIEldByname("name") //panic: reflect: call of reflect.Value.FIEldByname on ptr Value //b是一个指针,指针的ValueOf返回的是指针的Type,它是没有FIEld的,所以也就不能使用FIEldByname fmt.Println("--------------") fmt.Println(reflect.ValueOf(a).FIEldByname("name").CanSet()) fmt.Println(reflect.ValueOf(&(a.name)).Elem().CanSet()) fmt.Println("--------------") var c string = "xyz" p := reflect.ValueOf(&c) fmt.Println(p.CanSet()) //false fmt.Println(p.Elem().CanSet()) //true p.Elem().SetString("newname") fmt.Println(c)}
执行结果:
--------------<main.MyStruct Value><*main.MyStruct Value>--------------abc--------------falsetrue--------------falsetruenewname
a和b的ValueOf()返回的是不一样的值,因为b是用new()创建的,是个指针。
当前面的CanSet是一个指针的时候(p)它是不可寻址的,但是当是p.Elem()(实际上就是*p),它就是可以寻址的。
总结以上是内存溢出为你收集整理的golang小程序试验(三)全部内容,希望文章能够帮你解决golang小程序试验(三)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)