Loading

02 Go标准库

1 time

package main

// time模块

// 时间类型
//func main() {
//now := time.Now() // 获取当前时间
//fmt.Println(now)
//
//year := now.Year()
//month := now.Month()
//day := now.Day()
//hour := now.Hour()
//minute := now.Minute()
//second := now.Second()
//fmt.Printf("%d-%02d-%02d-%02d:%02d:%02d", year, month, day, hour, minute, second)
//}

// 时间戳
//func main() {
//now := time.Now()
//timestamp1 := now.Unix() //秒级时间戳
//timestamp2 := now.UnixNano() //纳秒级时间戳
//fmt.Printf("current timestamp1:%v\n", timestamp1)
//fmt.Printf("current timestamp2:%v\n", timestamp2)
//// 将时间戳转为时间格式
//timestamp3 := now.Unix()
//timeObj := time.Unix(timestamp3, 0)
//year := timeObj.Year()
//fmt.Println(year)
//}

// 时间间隔、纳秒、微妙、毫秒、秒、分、时
//func main() {
////const (
////Nanosecond Duration = 1
////Microsecond         = 1000 * Nanosecond
////Millisecond         = 1000 * Microsecond
////Second               = 1000 * Millisecond
////Minute               = 60 * Second
////Hour                 = 60 * Minute
////)
//time.Sleep(time.Millisecond * 20) //暂停20s
//}

// 时间格式化
//func main() {
//// 按格式模板进行时间格式化
//now := time.Now()
//s1 := now.Format("2006-01-02 15:04:05 Mon Jan")
//fmt.Println(s1)
//// 字符串转时间类型
//loc, _ := time.LoadLocation("Asia/Shanghai")
//timeObj, err := time.ParseInLocation("2006-01-02 15:04:05", "2022-03-27 20:49:20", loc)
//if err != nil {
// fmt.Println(err)
// return
//}
//fmt.Println(timeObj)
//}

// 时间操作函数
//func main() {
//// Add 方法,1分钟前
//now := time.Now()
//fmt.Println("now:", now)
//m, _ := time.ParseDuration("-1m")
//m1 := now.Add(m)
//fmt.Println("now add - 1m:", m1)
//// Add 方法,1分钟之后
//mm, _ := time.ParseDuration("1m")
//mm1 := now.Add(mm)
//fmt.Println("now add + 1m", mm1)
//// Sub方法,两个时间差
//fmt.Println(now.Sub(m1))
//}

2 fmt

package main

////占位符
//func main() {
//fmt.Println("张三", "李四", "王二")
//name := "张三"
//age := 20
//fmt.Printf("%s 今年 %d 岁\n", name, age)
//fmt.Printf("值: %v ---> 类型: %T", name, name)
//}

// Sprint -> 把传入的数据生成并返回一个字符串
//func main() {
//s1 := fmt.Sprintf("枯藤")
//fmt.Println(s1)
//name := "枯藤"
//age := 20
//s2 := fmt.Sprintf("name:%s age:%d", name, age)
//fmt.Println(s2)
//s3 := fmt.Sprintln("枯藤")
//fmt.Println(s3)
//s4 := fmt.Sprint("hh")
//fmt.Println(s4)
//s5 := fmt.Sprintf("1")
//fmt.Println(s5)
//}

3 net/http

index.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:9090/post" enctype="application/x-www-form-urlencoded" method="post">
    <label>
       姓名: <input type="text" name="name">
    </label>
    <label>
        <br/>
       年龄: <input type="text" name="age">
    </label>
    <br/>
   提交:<input type="submit">
</form>
</body>
</html>

main.go

package main

import (
"fmt"
"io"
"io/ioutil"
"net/http"
)

// net/http包实现http客户端和服务端

// get请求网站示例
func getBaidu(url string) {
resp, err := http.Get(url)
if err != nil {
fmt.Printf("get failed,err:%v\n", err)
return
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
fmt.Printf("resp status failed, err:%v\n", err)
return
}
}(resp.Body)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("read from resp.Body failed, err:%v", err)
return
}
fmt.Println(string(body))
}

func testServer(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("这是http server端"))
if err != nil {
fmt.Println("test server failed!")
return
}
}

// 带参数的get
func getHandler(w http.ResponseWriter, r *http.Request) {
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
fmt.Println("request close failed!", err)
return
}
}(r.Body)
data := r.URL.Query()
fmt.Println(data.Get("name"))
fmt.Println(data.Get("age"))
_, err := w.Write([]byte(`{"status":ok}`))
if err != nil {
fmt.Println("response failed!", err)
return
}
}

// post请求
func postHandler(w http.ResponseWriter, r *http.Request) {
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
fmt.Println(err)
return
}
}(r.Body)
// 1. 请求类型是application/x-www-form-urlencoded时解析form数据
err := r.ParseForm()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("打印form数据", r.PostForm)
fmt.Println("打印form数据", r.PostForm.Get("name"), r.PostForm.Get("age"))
// 2. 请求类型是application/json时从r.Body读取数据
//b, err := ioutil.ReadAll(r.Body)
//if err != nil {
//fmt.Println(err)
//return
//}
//fmt.Println(string(b))
_, err = w.Write([]byte(`"status": "ok"`))
if err != nil {
fmt.Println(err)
return
}
}

func main() {
// get请求网站示例
//getBaidu("https://taobao.com")

// 路由服务
// http://127.0.0.1:9090/
http.HandleFunc("/", testServer)
// http://127.0.0.1:9090/get?name="小王子"&age=18
http.HandleFunc("/get", getHandler)
/*输出结果
"小王子"
19
*/
// 访问index.html
http.HandleFunc("/post", postHandler)
/* 输出结果
打印form数据 map[age:[18] name:[刘畅]]
打印form数据 刘畅 18
*/

// 启动服务
fmt.Println("http server http://127.0.0.1:9090 start")
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Printf("http server failed, err:%v\n", err)
return
}
}

4 strconv

package main

import (
"fmt"
"strconv"
)

// strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数: Atoi()、Itoa()、parse系列、format系列、append系列。
// base指定进制(2到36),如果base为0,则会从字符串前置判断,”0x”是16进制,”0”是8进制,否则是10进制;
// bitSize指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64;

// Atoi() 函数用于将字符串类型的整数转换为int类型
func strToInt() {
s1 := "100"
i1, err := strconv.Atoi(s1)
if err != nil {
fmt.Println("can't convert to int", err)
return
}
fmt.Printf("Type:%T value:%#v", i1, i1)
}

//Itoa()函数将int类型数据转换为对应的字符串表示
func intToStr() {
i2 := 200
s2 := strconv.Itoa(i2)
fmt.Printf("Type:%T value:%#v", s2, s2)
}

//Parse类函数用于转换字符串为给定类型的值:ParseBool()、ParseFloat()、ParseInt()、ParseUint()。
func parseStrTo() {
//1、字符串转Bool
b, err := strconv.ParseBool("true")
if err != nil {
fmt.Println("can't convert to bool", err)
return
}
fmt.Printf("type:%T value:%#v\n", b, b)

//2、字符串转Float
f, err := strconv.ParseFloat("3.1415", 64)
if err != nil {
fmt.Println("can't convert str to float", err)
return
}
fmt.Printf("Type:%T value:%#v\n", f, f)
//3、字符串转Int(接受正负号)
i, err := strconv.ParseInt("-100", 10, 64)
if err != nil {
fmt.Println("can't str to int", err)
}
fmt.Printf("Type:%T value:%#v\n", i, i)
//4、字符串转Uint(不接受正负号)
u, err := strconv.ParseUint("200", 10, 64)
if err != nil {
fmt.Println("can't str to Unit", err)
}
fmt.Printf("Type:%T value:%v\n", u, u)
}

// Format系列函数实现了将给定类型数据格式化为string类型数据的功能。
func formatToStr() {
//1、Bool转字符串
b := strconv.FormatBool(true)
fmt.Printf("type:%T value:%#v\n", b, b)
//2、Float转字符串
f := strconv.FormatFloat(3.1415, 'f', -1, 64)
fmt.Printf("Type:%T value:%#v\n", f, f)
//3、Int转字符串(接受正负号)
i := strconv.FormatInt(-100, 10)
fmt.Printf("Type:%T value:%#v\n", i, i)
//4、Uint(不接受正负号)转字符串
u := strconv.FormatUint(200, 10)
fmt.Printf("Type:%T value:%v\n", u, u)
}

func main() {
//strToInt()
//intToStr()
//parseStrTo()
//formatToStr()
}

5 OS

package main

import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)

//os标准库
//func main() {
//1、获取当前目录
//fmt.Println(os.Getwd())
//2、修改当前目录
//err := os.Chdir("d:\\code\\GoCode")
//if err != nil {
//return
//}
//fmt.Println(os.Getwd())
//3、创建文件夹
//err := os.Mkdir("lc_dir", 777)
//if err != nil {
//return
//}
//4、删除文件或者文件夹
//err := os.Remove("lc_dir")
//if err != nil {
//return
//}
//5、修改文件夹或文件的名称
//err := os.Rename("lc.txt", "chang.txt")
//if err != nil {
//return
//}
//6、新建文件
//_, err := os.Create("lc.txt")
//if err != nil {
//return
//}
//7、打开文件并写入文件
/*
   O_RDONLY 打开只读文件
  O_WRONLY 打开只写文件
  O_RDWR   打开既可以读取又可以写入文件
  O_APPEND 写入文件时将数据追加到文件尾部
  O_CREATE 如果文件不存在,则创建一个新的文件
*/
//file, err1 := os.OpenFile("file.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 644)
//if err1 != nil {
//return
//}
//_, err2 := file.WriteString(",你好222")
//if err2 != nil {
//return
//}
//err3 := file.Close()
//if err3 != nil {
//return
//}
//}

//// 从文件中读取指定字节数
//func main() {
//fileObj, err := os.Open("./15OS/os.txt")
//if err != nil {
// fmt.Printf("open file error,err:%v\n", err)
// return
//}
////关闭文件
//defer func(fileObj *os.File) {
// err := fileObj.Close()
// if err != nil {
// return
// }
//}(fileObj)
////读取文件内容
//var tmp = make([]byte, 128)
//n, err := fileObj.Read(tmp)
//if err != nil {
// fmt.Printf("read from file failed,err:%v\n", err)
// return
//}
//fmt.Printf("read %d bytes from file.\n", n)
//fmt.Println(string(tmp[:n]))
//}

// 循环读取文件中所有的字节数,需要每次指定读取的字节数
//func main() {
//fileObj, err := os.Open("./15OS/os.txt")
//if err != nil {
// fmt.Printf("open file error,err:%v\n", err)
// return
//}
////关闭文件
//defer func(fileObj *os.File) {
// err := fileObj.Close()
// if err != nil {
// return
// }
//}(fileObj)
////读取文件内容
//var content []byte
//var tmp = make([]byte, 128)
//for {
// n, err := fileObj.Read(tmp)
// if err == io.EOF { // EOF => End Of File
// fmt.Println("文件读完了")
// break
// }
// if err != nil {
// fmt.Printf("read from file failed,err:%v\n", err)
// return
// }
// fmt.Printf("read %d bytes from file.\n", n)
// content = append(content, tmp[:n]...)
//}
////fmt.Printf("%#v", string(content))
//fmt.Println(string(content))
//}

// read by bufio从文件中读取文件,一行一行的读取
//func main() {
//fileObj, err := os.Open("./15OS/os.txt")
//if err != nil {
// fmt.Printf("open file error,err:%v\n", err)
// return
//}
////关闭文件
//defer func(fileObj *os.File) {
// err := fileObj.Close()
// if err != nil {
// return
// }
//}(fileObj)
////读取文件内容
//reader := bufio.NewReader(fileObj)
//for {
// line, err := reader.ReadString('\n')
// if err == io.EOF {
// if len(line) != 0 {
// fmt.Println(line)
// }
// fmt.Println("文件读完了")
// return
// }
// if err != nil {
// fmt.Println("read file failed,err:", err)
// return
// }
// //fmt.Printf("%#v", line)
// fmt.Print(line)
//}
//}

// ioutil读取整个文件内容
//func main() {
//content, err := ioutil.ReadFile("./15OS/os.txt")
//if err != nil {
// fmt.Println("read file failed, err:", err)
// return
//}
//fmt.Println(string(content))
//}

// 文件写入操作Write、WriteString
func writeString(str string, fileName string) {
file, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("open file failed, err:", err)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
fmt.Println("open file close failed, err:", err)
return
}
}(file)
_, err = file.Write([]byte(str)) //写入字节切片数据
if err != nil {
fmt.Println("write file failed, err:", err)
return
}
_, err = file.WriteString(str) // 直接写入字符串数据
if err != nil {
fmt.Println("writeString file failed, err:", err)
return
}
}

// bufio.NewWriter,写缓存
func bufIoCache(str string, fileName string) {
file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 644)
if err != nil {
fmt.Println("open file failed, err:", err)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
fmt.Println("open file close failed, err:", err)
return
}
}(file)
// 先将数据写到缓存
write := bufio.NewWriter(file)
_, err = write.WriteString(str)
if err != nil {
fmt.Println("writeString file failed, err:", err)
return
}
//将缓存中的内容写入文件
err = write.Flush()
if err != nil {
fmt.Println("writeString file flush failed, err:", err)
return
}
}

// ioutil.WriteFile,一次性写入,覆盖之前的内容
func ioUtilWriteFile(str, fileName string) {
err := ioutil.WriteFile(fileName, []byte(str), 0664)
if err != nil {
fmt.Println("write file failed, error:", err)
return
}
}

// io.Copy() 实现文件copy操作,可以复制文本或二进制文件
func copyFile(dstName, srcName string) (written int64, err error) {
//以读的方式打开源文件
src, err := os.Open(srcName)
if err != nil {
fmt.Printf("open %s failed ,err:%v.\n", srcName, err)
return
}
defer func(src *os.File) {
err := src.Close()
if err != nil {
fmt.Printf("src %s close failed, err:%v", srcName, err)
return
}
}(src)
// 以写|创建的方式打开目标文件
dst, err := os.OpenFile(dstName, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Printf("open %s failed, err:%v. \n", dstName, err)
}
defer func(dst *os.File) {
err := dst.Close()
if err != nil {
fmt.Printf("close %s failed, err:%v.\n", dstName, err)
return
}
}(dst)
//调用io.Copy()拷贝内容
return io.Copy(dst, src)
}

func main() {
// 文件写入操作Write、WriteString
//writeString("你好,中国\n", "15OS/out.txt")

// bufio.NewWriter,写缓存
//bufIoCache("爱拼才会赢\n", "15OS/out.txt")

// ioutil.WriteFile,一次性写入,覆盖之前的内容
//ioUtilWriteFile("努力学习go语言", "15OS/out.txt")

// io.Copy() 实现文件copy操作,可以复制文本或二进制文件
//_, err := copyFile("15OS/sogou_pinyin1.exe", "15OS/sogou_pinyin.exe")
//if err != nil {
//fmt.Println("copy file failed,err", err)
//return
//}
//fmt.Println("copy done!")
}

6 flag

package main

import (
"flag"
"fmt"
"os"
"time"
)

// Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单。

// os.Args
//如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用os.Args来获取命令行参数。
//os.Args是一个存储命令行参数的字符串切片,它的第一个元素是执行文件的名称。
func argsLen() {
if len(os.Args) > 0 {
for index, arg := range os.Args {
fmt.Printf("args[%d]=%v\n", index, arg)
}
}
}

// flag包基本使用:
// flag包支持的命令行参数类型有bool、int、int64、uint、uint64、float float64、string、duration。
// 指定命令行参数时覆盖默认命令行参数,不指定命令行参数时使用默认命令行参数
/*
支持的命令行参数格式有以下几种:

-flag xxx (使用空格,一个-符号)
--flag xxx (使用空格,两个-符号)
-flag=xxx (使用等号,一个-符号)
--flag=xxx (使用等号,两个-符号)
其中,布尔类型的参数必须使用等号的方式指定。
*/

// flag.Type()
// 需要注意的是,此时name、age、married、delay均为对应类型的指针。
// flag.Type(flag名, 默认值, 帮助信息) *Type
func flagType() {
name := flag.String("name", "张三", "姓名")
age := flag.Int("age", 18, "年龄")
married := flag.Bool("married", false, "婚否")
delay := flag.Duration("delay", 0, "时间间隔")
flag.Parse()
fmt.Println(flag.Args())  //返回命令行参数后的其他参数,以[]string类型
fmt.Println(flag.NArg())  //返回命令行参数后的其他参数个数
fmt.Println(flag.NFlag()) //返回使用的命令行参数个数
fmt.Println(*name, *age, *married, *delay)
}

// flag.TypeVar()
// 需要注意的是,此时name、age、married、delay均不为对应类型的指针。
// flag.TypeVar(Type指针, flag名, 默认值, 帮助信息)
func flagTypeVar() {
var name string
var age int
var married bool
var delay time.Duration
flag.StringVar(&name, "name", "张三", "姓名")
flag.IntVar(&age, "age", 18, "年龄")
flag.BoolVar(&married, "married", false, "婚否")
flag.DurationVar(&delay, "delay", 0, "时间间隔")
flag.Parse()
fmt.Println(flag.Args())  //返回命令行参数后的其他参数,以[]string类型
fmt.Println(flag.NArg())  //返回命令行参数后的其他参数个数
fmt.Println(flag.NFlag()) //返回使用的命令行参数个数
fmt.Println(name, age, married, delay)
}

func main() {
//argsLen()
//flagType()
flagTypeVar()
}

/*
PS D:\Code\GoCode\hello\16flag> go build main.go

PS D:\Code\GoCode\hello\16flag> .\main.exe -h
Usage of D:\Code\GoCode\hello\16flag\main.exe:
  -age int
        年龄 (default 18)
  -delay duration
        时间间隔
 -married
        婚否
 -name string
        姓名 (default "张三")

PS D:\Code\GoCode\hello\16flag> .\main.exe -name 刘畅 --age 27 -married=true -delay 10000h0m0s
[]
0
4
刘畅 27 true 10000h0m0s

PS D:\Code\GoCode\hello\16flag> .\main.exe a b c
[a b c]
3
0
张三 18 false 0s
*/

7 log

main.go

package main

import (
"fmt"
"log"
"os"
)

// log
// 无论是软件开发的调试阶段还是软件上线之后的运行阶段,日志一直都是非常重要的一个环节,我们也应该养成在程序中记录日志的好习惯。
// Go语言内置的log包实现了简单的日志服务。

// log common01
// logger会打印每条日志信息的日期、时间,默认输出到系统的标准错误。
// Fatal系列函数会在写入日志信息后调用os.Exit(1)。Panic系列函数会在写入日志信息后panic。
func logCommon() {
log.Println("这是一条很普通的日志")
v := "很普通的"
log.Printf("这是一条%s日志", v)
log.Fatalln("这是一条会触发fatal的日志")
//log.Panicln("这是一条会触发panic的日志")
}

//配置日志格式
/*
log标准库提供了如下的flag选项,它们是一系列定义好的常量。
const (
    // 控制输出日志信息的细节,不能控制输出的顺序和格式。
   // 输出的日志在每一项后会有一个冒号分隔:例如2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
    Ldate         = 1 << iota     // 日期:2009/01/23
    Ltime                         // 时间:01:23:23
    Lmicroseconds                 // 微秒级别的时间:01:23:23.123123(用于增强Ltime位)
   Llongfile                     // 文件全路径名+行号: /a/b/c/d.go:23
    Lshortfile                   // 文件名+行号:d.go:23(会覆盖掉Llongfile)
   LUTC                         // 使用UTC时间
   LstdFlags     = Ldate | Ltime // 标准logger的初始值
)
*/
func setLogFlag() {
log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
}

// 配置日志前缀
func setLogPreFix() {
log.SetPrefix("[goLog]")
}

// 配置日志输出位置
func setLogLocation() {
logfile, err := os.OpenFile("./17log/go.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Println("open log file failed, err:", err)
return
}
log.SetOutput(logfile)
}

func main() {
setLogPreFix()
setLogFlag()
setLogLocation()
logCommon()
}

/*
[goLog]2022/03/30 01:08:29.941318 D:/Code/GoCode/hello/17log/main.go:17: 这是一条很普通的日志
[goLog]2022/03/30 01:08:29.976345 D:/Code/GoCode/hello/17log/main.go:19: 这是一条很普通的日志
[goLog]2022/03/30 01:08:29.976345 D:/Code/GoCode/hello/17log/main.go:20: 这是一条会触发fatal的日志
*/

log_init.go

package main

import (
"fmt"
"log"
"os"
)

//如果你要使用标准的logger,我们通常会把上面的配置操作写到init函数中。
func init() {
logFile, err := os.OpenFile("./17log/go.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Println("open log file failed, err:", err)
return
}
log.SetPrefix("[goLog]")
log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
log.SetOutput(logFile)
}

func logCommon2() {
log.Println("这是一条很普通的日志")
v := "很普通的"
log.Printf("这是一条%s日志", v)
log.Fatalln("这是一条会触发fatal的日志")
//log.Panicln("这是一条会触发panic的日志")
}

func main() {
logCommon2()
}


posted @ 2022-05-18 13:37  云起时。  阅读(42)  评论(0编辑  收藏  举报