Golang常用库学习 - Go语言中文社区

Golang常用库学习


标准库fmt

  • fmt.Fprintf 向文件中写内容
  • 格式化字符串
  • 获取标准输入,输入字段以空格分割
  • 获取标准输入,若用户输入包含空格,使用bufio实现

func main() {
	// fmt.Fprintf 向文件中写内容
	fileObj, err := os.OpenFile("./a.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer fileObj.Close()
	s := "text"
	fmt.Fprintf(fileObj, "%s\n", s)

	// 格式化字符串
	o := struct{ name string }{"zzdd"}
	fmt.Printf("%v\n", o)  // 值的默认格式
	fmt.Printf("%+v\n", o) // 同时输出字段名
	fmt.Printf("%#v\n", o) // 值的go语法
	fmt.Printf("%T\n", o)  // 值的类型
	fmt.Printf("100%%\n")  // 打印百分号

	// 获取标准输入,输入字段以空格分割
	// var (
	// 	name string
	// 	age  int
	// )
	// fmt.Print("please input your name and age: ")
	// fmt.Scan(&name, &age) // 注意这里的符号 &
	// fmt.Printf("name: %s age: %d\n", name, age)

	// 获取标准输入,若用户输入包含空格,使用bufio实现
	reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象
	fmt.Print("请输入: ")
	text, _ := reader.ReadString('\n') // 读到换行
	text = strings.TrimSpace(text)
	fmt.Printf("%#v\n", text)
}
/* 
========== 
{zzdd}
{name:zzdd}
struct { name string }{name:"zzdd"}
struct { name string }
100%
请输入: qq is good
"qq is good"
*/

标准库log

// 一个好的实践是将这部分通用配置放到init函数中
func init() {
	logFile, err := os.OpenFile("./a.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatal(err)
		return
	}
	// 将日志写入文件
	log.SetOutput(logFile)
	// 控制输出日志信息的细节
	log.SetFlags(log.Lshortfile | log.Lmicroseconds | log.Ldate)
	// 配置日志信息前缀
	log.SetPrefix("[prefix_name] ")
}

func main() {
	// log.New 可以自定义日志输出
	// func New(out io.Writer, prefix string, flag int) *Logger
	logger := log.New(os.Stdout, "[prefix New] ", log.Lshortfile|log.Ldate|log.Ltime)
	logger.Println("logger log")
	log.Println("i am log")
	v := "this is log"
	log.Printf("%s", v)
	// log.Fatalln("fatal") // Fatalln会在写入日志后调用os.Exit(1)
	/*
		[prefix New] 2021/03/16 09:57:35 main.go:27: logger log
		cat a.log
		[prefix_name] 2021/03/16 10:00:25.470469 main.go:28: i am log
		[prefix_name] 2021/03/16 10:00:25.470494 main.go:30: this is log
	*/
}

标准库time

时间类型输出
unix时间戳
定时器
格式化时间(Go的诞生时间2006年1月2号15点04分)

package main

import (
	"fmt"
	"time"
)

func main() {
	// 时间类型
	now := time.Now()    // 当前时间
	year := now.Year()   // 当前年
	month := now.Month() // 当前月
	day := now.Day()
	fmt.Println(now)
	fmt.Printf("%d-%d-%d\n", year, month, day)
	timestamp := now.Unix() // 当前unix时间戳
	fmt.Printf("%v\n", timestamp)

	// 时间戳
	timeObj := time.Unix(timestamp, 0) // 将unix时间戳转换为时间
	fmt.Println(timeObj)
	hour := timeObj.Hour()     //时
	minute := timeObj.Minute() //分
	second := timeObj.Second() //秒
	fmt.Printf("%d:%d:%d\n", hour, minute, second)

	// 定时器
	// ticker := time.Tick(time.Second) // 间隔1秒
	// for i := range ticker {
	// 	fmt.Println(i)
	// }
	// 格式化时间,按照Go的诞生时间2006年1月2号15点04分
	// 24小时制
	fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
	// 12小时制
	fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
}
/*
========================
2021-03-15 18:18:32.977383 +0800 CST m=+0.000065185
2021-3-15
1615803512
2021-03-15 18:18:32 +0800 CST
18:18:32
2021-03-15 18:18:32.977 Mon Mar
2021-03-15 06:18:32.977 PM Mon Mar
*/

标准库strconv

strconv实现了基本数据类型和其字符串表示的相互转换。

  • int类型转化为string类型
  • str类型转化为int类型
  • Parse函数:转换字符串为给定类型的值
  • Format函数:将给定类型数据格式化为string类型
func main() {
	// int类型转化为string类型
	var i int = 4
	var itostr string = strconv.Itoa(i)
	fmt.Println(reflect.TypeOf(itostr), itostr)

	// str类型转化为int类型
	var str string = "5"
	strtoi, err := strconv.Atoi(str)
	if err != nil {
		fmt.Println("convert failed")
	}
	fmt.Println(reflect.TypeOf(strtoi), strtoi)

	// Parse函数用于转换字符串为给定类型的值
	b1, err := strconv.ParseBool("true")
	f1, err := strconv.ParseFloat("3.141", 64)
	i1, err := strconv.ParseInt("-2", 10, 64)
	u1, err := strconv.ParseUint("2", 10, 64)
	fmt.Println(reflect.TypeOf(b1), b1)
	fmt.Println(reflect.TypeOf(f1), f1)
	fmt.Println(reflect.TypeOf(i1), i1)
	fmt.Println(reflect.TypeOf(u1), u1)

	//Format函数实现了将给定类型数据格式化为string类型数据的功能
	s1 := strconv.FormatBool(true)
	s2 := strconv.FormatFloat(3.1415, 'E', -1, 64)
	s3 := strconv.FormatInt(-2, 16)
	s4 := strconv.FormatUint(2, 16)
	fmt.Println(reflect.TypeOf(s1), s1)
	fmt.Println(reflect.TypeOf(s2), s2)
	fmt.Println(reflect.TypeOf(s3), s3)
	fmt.Println(reflect.TypeOf(s4), s4)

}
/*
string 4
int 5
bool
string true
bool true
float64 3.141
int64 -2
uint64 2
string true
string 3.1415E+00
string -2
string 2
*/
}

标准库 testing

单元测试

约定1:与测试的代码在同级目录,并以 “文件名_test.go” 命名
约定2:测试函数以Test开头
约定3:got want模式,有助于快速发现失败的原因

简单测试

a.go

func Greeting(s string) string {
	return ("hello " + s)
}

a_test.go

func TestGreeting(t *testing.T) { // TestGreeting因为是Test开头,表明是一个测试,类型T包含很多用于测试代码的函数
	got := Greeting("zzd") // got表示要测试的值
	want := "hello zzd" //  want表示期望的值
	if got != want {
		t.Fatalf("expected %v, got %v", want, got) // 错误友情提示
	}
}
/*
终端执行
go test,显示测试结果,若将want内容修改为其它,则会打印错误友情提示
PASS
ok      06      0.017s
*/

单元测试覆盖率统计

go test -cover

PASS
coverage: 33.3% of statements
ok      06      0.017s

表格驱动测试

// 定义转化函数,匹配输入
func translate(s string) string {
	switch s {
	case "zh-gz":
		return "hello "
	case "zh-bj":
		return "hi "
	case "zh-sh":
		return "good "
	default:
		return "hello "
	}
}

// 定义got拼接
func Greeting(name, locale string) string {
	salutation := translate(locale)
	return (salutation + name)
}

// 使用表格驱动测试,能够同时测试很多条件
type GreetingTest struct {
	name   string
	locale string
	want   string
}

// 表格数据赋值
var greetingTests = []GreetingTest{
	{"aaa", "zh-gz", "hello aaa"},
	{"ddd", "zh-bj", "hi ddd"},
	{"ccc", "zh-sh", "good ccc"},
}

func TestGreeting(t *testing.T) { // TestGreeting因为是Test开头,表明是一个测试,类型T包含很多用于测试代码的函数
	for _, test := range greetingTests {
		got := Greeting(test.name, test.locale)
		if got != test.want {
			t.Errorf("Greeting(%s,%s)=%v;want %v", test.name, test.locale, got, test.want)
		}
	}
}
/*
go test
PASS
ok      06      0.017s
*/

性能(基准)测试

package temp

import (
	"bytes"
	"strings"
	"testing"
)

// 字符串拼接几种方法性能(基准)测试,
// 1、直接赋值
func StringAssign(j int) string {
	var s string
	for i := 0; i < j; i++ {
		s += "a"
	}
	return s
}

// 2、使用join赋值
func StringAppend(j int) string {
	s := []string{}
	for i := 0; i < j; i++ {
		s = append(s, "a")
	}
	return strings.Join(s, "")
}

// 3、使用缓冲区赋值
func StringBuffer(j int) string {
	var buffer bytes.Buffer
	for i := 0; i < j; i++ {
		buffer.WriteString("a")
	}
	return buffer.String()
}

// 性能(基准)测试需要以Benchmark打头,接受一个类型为B的参数,并对函数进行基准测试
func BenchmarkStringAssign(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StringAssign(100)
	}
}

func BenchmarkStringAppend(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StringAppend(100)
	}
}

func BenchmarkStringBuffer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StringBuffer(100)
	}
}

/*
//终端执行,结论:缓冲区速度最快
go test -bench=.

BenchmarkStringAssign-12          284379              3896 ns/op
BenchmarkStringAppend-12          558100              1974 ns/op
BenchmarkStringBuffer-12         1902393               632 ns/op
PASS
ok      06      4.138s
*/

标准库 os

文件操作

// 将日志写入文件
	f, err := os.OpenFile("stdout.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()  // defer延时关闭文件
	log.SetOutput(f) // 通过SetOutput可以将标准输出直接输出到文件
	var count = 5
	for i := 0; i < count; i++ {
		log.Printf("log iteration %d", i)
	}

ioutil包用于执行一些常见的文件处理操作,底层使用os包,复杂操作可以用os包


/*
*/

type Config struct {
	Name string  `json:name`
	Age  float64 `json:age`
	God  bool    `json:god`
}

func main() {
	// 读取文件
	fileBytes, err := ioutil.ReadFile("stdout.log") // 返回一个字节切片
	if err != nil {
		log.Fatal(err)
	}
	fileString := string(fileBytes) // 将字节切片转换为字符串
	fmt.Println(fileString)
	// 创建文件
	b := make([]byte, 0) // WriteFile需接受字节切片,创建一个,并给文件赋权
	err1 := ioutil.WriteFile("err.log", b, 0644)
	if err1 != nil {
		log.Fatal(err1)
	}
	// 将文本写入文件,文件不存在则创建
	s := "hello world"
	err2 := ioutil.WriteFile("err1.log", []byte(s), 0644)
	if err != nil {
		log.Fatal(err2)
	}
	// 列出当前目录内容,ReadDir返回列表,包含Name、Size等
	files, err3 := ioutil.ReadDir(".")
	if err3 != nil {
		log.Fatal(err3)
	}
	for _, file := range files {
		fmt.Println(file.Name(), file.Size(), file.IsDir(), file.Mode(), file.ModTime())
	}
	// 复制文件,使用os
	from, err := os.Open("err1.log") // 读取文件
	if err != nil {
		log.Fatal(err)
	}
	defer from.Close() // 一定不要忘记关闭文件

	to, err := os.OpenFile("err1.copy", os.O_RDWR|os.O_CREATE, 0666) // 打开文件
	if err != nil {
		log.Fatal(err)
	}
	defer to.Close() // 一定不要忘记关闭文件

	_, err = io.Copy(to, from) // io.Copy(目标,来源)
	if err != nil {
		log.Fatal(err)
	}
	// 删除文件,需要先判断是否存在
	// err5 := os.Remove("./err.log")
	// if err5 != nil {
	// 	log.Fatal(err5)
	// }
	// 从json文件中读取配置
	f, err := ioutil.ReadFile("config.json")
	if err != nil {
		log.Fatal(err)
	}
	c := Config{}
	err = json.Unmarshal(f, &c) // json解码
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%+v\n", c.Name)

}

标准库 flag

简单命令行传参

func main() {
	
	// 1.获取命令行参数os.Args
	// for i, arg := range os.Args {
	// 	fmt.Println("arg:", i, arg)
	// }
	
	// 2.获取命令行参数使用flag包
	// flag.Usage自定义帮助文本
	flag.Usage = func() {
		usageText := `Usage cli [OPTION]
		An example of customizing usage output
		-s, --s		string help text
		-i, --i		int help text
		-b, --b		bool help text
		`
		fmt.Fprintln(os.Stderr, usageText)

	}
	// flag.String表示接收string类型参数
	s := flag.String("s", "hi", "string help text")
	i := flag.Int("i", 1, "int help text")
	b := flag.Bool("b", false, "bool help text")
	//flag.Parse 传递声明的参数
	flag.Parse()
	fmt.Println("value of s:", *s)
	fmt.Println("value of i:", *i)
	fmt.Println("value of b:", *b)
}

复杂命令行参数(子命令)

func flagUsage() {
	usageText := `script is a string handle cli tool.
Usage:
./script command [arguments]
The commands are:
	upper 
	lower
Use "./script [command] --help" for more information about a command.
	`
	fmt.Fprintf(os.Stderr, "%s\n", usageText)
}

func main() {
	// flag.Usage自定义帮助文本
	flag.Usage = flagUsage
	// 添加子命
                        
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_16240085/article/details/114837820
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2023-01-03 20:59:02
  • 阅读 ( 223 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢