• golang学习笔记系列之一些标准库的学习(log,bytes,errors等)


    log

    golang内置了log包,实现了简单的日志服务。通过调用log包的函数,可以实现简单的日志打印功能。

    log包中有3个系列的日志打印函数,分别是print系列,panic系列和fatal系列。

    函数系列作用
    print单纯打印日志
    panic打印日志,抛出panic异常
    fatal打印日志,强制结束程序(os.Exit(1)),defer函数不会执行
    package main
    
    import (
    	"fmt"
    	"log"
    	"os"
    )
    
    func main() {
    
    	//配置日志的输出前缀
    	log.SetPrefix("Log:")
    
    	//配置日志
    	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Llongfile)
    
    	//设置日志输出到文件
    	f, _ := os.OpenFile("a.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, os.ModePerm)
    	defer f.Close()
    	log.SetOutput(f)
    
    	//简单打印日志
    	log.Print("hello golang...")
    	defer fmt.Print("程序结束...")
    	//panic日志
    	// log.Panic("bye...") //defer会被执行
    
    	//fatal日志
    	// log.Fatal("致命错误...") //defer不会被执行
    
    	//自定义logger
    	my_logger := log.New(os.Stdout, "My Log:", log.Ldate|log.Ltime|log.Lmicroseconds|log.Llongfile)
    	my_logger.Print("这个是自己定义的logger,一次性配置所有,会方便许多!")
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    运行结果

    My Log:2022/11/05 17:27:35.150644 /home/lll/Desktop/go/lll08_标准库/os/lll07_日志相关的操作.go:33: 这个是自己定义的logger,一次性配置所有,会方便许多!
    
    • 1

    builtin

    这个包提供了一些类型声明,变量和常量声明,还有一些便利的函数,这个包不需要导入,这些变量和函数就可以直接使用。

    panic

    抛出一个panic异常。

    package main
    
    import "fmt"
    
    func main() {
    
    	//panic 抛出异常
    	panic("抛出异常!!!")
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    new和make

    new和make的区别:

    1. make只能用来分配及初始化类型为slice,map和chan的数据;new可以分配任意类型的数据
    2. new分配返回的是指针,即类型为*T;make返回的是数据的值,即T
    3. make分配后会对数据进行初始化,而new不会
    package main
    
    import "fmt"
    
    func main() {
    
    
    	s := new(string)
    	fmt.Printf("s: %T\n", s) //*string
    	fmt.Printf("s: %v\n", *s)
    
    	i2 := new([]int)
    	fmt.Printf("i2: %T\n", i2) //*[]int
    	fmt.Printf("i2: %v\n", *i2)
    
    	i3 := make([]int, 10, 100) //初始化容量为100,长度为10
    	fmt.Printf("i3: %T\n", i3)
    	fmt.Printf("i3: %v\n", i3)
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行结果

    s: *string
    s: 
    i2: *[]int
    i2: []
    i3: []int
    i3: [0 0 0 0 0 0 0 0 0 0]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    内建函数make(T,args)与new(T)的用途不一样。它只用来创建slice,map和chan,并且返回一个初始化后的类型为T的数据。之所以不同,是因为这三个类型的背后引用了使用前必须初始化的数据结构。例如:slice是一个三元描述符,包含一个指向数据的指针,长度,以及容量,在这些项被初始化之前,slice都是nil。对于slice,map和chan,make初始化这些内部数据结构,并准备好可用的值。

    bytes

    bytes提供了对字节切片进行读写操作的一系列函数,字节切片处理函数比较多分为基本处理函数,比较函数,后缀检查函数,索引函数,分割函数,大小写处理函数和子切片处理函数。

    package main
    
    import (
    	"bytes"
    	"fmt"
    )
    
    func main() {
    
    	s1 := "hello world!"
    	b1 := []byte("你好,世界!")
    	fmt.Printf("s1: %v\n", s1)
    	fmt.Printf("b1: %v\n", b1)
    
    	//bytes和string的相互转换
    	//1.bytes转string
    	fmt.Printf("string(b1): %v\n", string(b1))
    	//2.string转bytes
    	fmt.Printf("[]byte(s1): %v\n", []byte(s1))
    
    	//contains:检查bytes中是否包含子bytes
    	fmt.Printf("bytes.Contains(b1, []byte(\"世界\")): %v\n", bytes.Contains(b1, []byte("世界")))
    
    	//count:统计某个bytes出现的次数
    	fmt.Printf("bytes.Count([]byte(s1), []byte(\"l\")): %v\n", bytes.Count([]byte(s1), []byte("l")))
    
    	//compare:比较两个bytes The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
    	fmt.Printf("bytes.Compare(b1, []byte(\"hello\")): %v\n", bytes.Compare(b1, []byte("hello")))
    
    	//分割bytes
    	before, after, _ := bytes.Cut(b1, []byte(","))
    	fmt.Printf("before: %v\n", string(before))
    	fmt.Printf("after: %v\n", string(after))
    
    	//连接bytes
    	b := bytes.Join([][]byte{b1, []byte(s1)}, []byte("==="))
    	fmt.Printf("b: %v\n", string(b))
    
    	//runes 转成utf8编码 这样能够正确计算中文长度
    	r := bytes.Runes(b1)
    	fmt.Printf("bytes.Runes(b1): %v\n", r)
    	fmt.Printf("len(r): %v\n", len(r))
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    运行结果

    s1: hello world!
    
    b1: [228 189 160 229 165 189 239 188 140 228 184 150 231 149 140 239 188 129]
    
    string(b1): 你好,世界!
    
    []byte(s1): [104 101 108 108 111 32 119 111 114 108 100 33]
    
    bytes.Contains(b1, []byte("世界")): true
    
    bytes.Count([]byte(s1), []byte("l")): 3
    
    bytes.Compare(b1, []byte("hello")): 1
    
    before: 你好
    
    after: 世界!
    
    b: 你好,世界!===hello world!
    
    bytes.Runes(b1): [20320 22909 65292 19990 30028 65281]
    
    len(r): 6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    errors

    errors包实现了操作错误的函数。go语言使用error类型来返回函数执行过程中遇到的错误,如果返回的error值为nil,则表示未遇到错误,否则error会返回一个字符串,用于说明遇到了什么错误。

    error的结构

    type error interface {
        Error() string
    }
    
    • 1
    • 2
    • 3

    你可以使用任何类型去实现它(只要添加一个Error()方法即可),也就是说,error可以是任何类型,这意味着,函数返回的error值实际可以包含任意信息,不一定是字符串。

    error不一定表示一个错误,它可以表示任何信息,比如io包中就用error类型的io.EOF表示数据读取结束,而不是遇到了什么错误。

    errors包实现了一个最简单的error类型,只包含了一个字符串,它可以记录大多数情况下遇到的错误信息。errors包的用法很简单,只有一个New函数,用于生成一个简单的error对象:

    func New(text string) error
    
    • 1
    package main
    
    import (
    	"errors"
    	"fmt"
    	"time"
    )
    
    //自定义errors
    type MyError struct {
    	When time.Time
    	What string
    }
    
    /*
    type error interface {
    	Error() string
    }
    
    
    error是一个接口,只要实现了Error方法,就可以是一个error
    
    */
    
    func (e MyError) Error() string {
    	return fmt.Sprintf("%v : %v", e.When, e.What)
    }
    
    //检测字符串是否为空
    func check_str(s string) (err error) {
    
    	if s == "" {
    		err = errors.New("字符串不能为空...")
    	} else {
    		err = MyError{
    			When: time.Date(2022, 11, 11, 11, 11, 11, 11, time.UTC),
    			What: fmt.Sprintf("%v 不是一个空字符串...", s),
    		}
    	}
    	return
    
    }
    func main() {
    
    	s := ""
    	err := check_str(s)
    	fmt.Printf("err: %v\n", err)
    	s2 := "hello python"
    	err2 := check_str(s2)
    	fmt.Printf("err2: %v\n", err2)
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    运行结果

    err: 字符串不能为空...
    err2: 2022-11-11 11:11:11.000000011 +0000 UTC : hello python 不是一个空字符串...
    
    • 1
    • 2

    同步更新于个人博客系统golang学习笔记系列之一些标准库的学习(log,bytes,errors等)

  • 相关阅读:
    Word控件Spire.Doc 【段落处理】教程(七):如如何通过在 C# 中附加 HTML 代码来设置 word 项目符号样式
    GeoServer运行报错503,……Unmapped relationship: 7
    JVM+java的类加载机制
    C++多线程同步(上)
    毕业设计-基于机器视觉深度学习船只船舶检测
    React整理总结(四)
    单片机C语言实例:32、实用密码锁
    聊一聊向上管理
    matlab求下列积分的数值解
    15种下载文件的方法&文件下载方法汇总&超大文件下载
  • 原文地址:https://blog.csdn.net/max_LLL/article/details/127717646