作用:统计某段代码的执行时间,花费时间等,需要导入time包
以下用一个函数包含所有使用方法
package main
import (
"fmt"
"time"
)
func main() {
/*
1. 获取当前时间。
*/
fmt.Println(time.Now())
// 2019-05-03 22:43:03.9052219 +0800 CST m=+0.005996401
// type = time.Time
/*
2. 获取当前的年月日时分秒
*/
fmt.Println(time.Now().Year()) //2019
fmt.Println(time.Now().Month()) //国外风格:May
fmt.Println(time.Now().int(Month())) //中国风:5
fmt.Println(time.Now().Day()) //3
fmt.Println(time.Now().Hour()) //22
fmt.Println(time.Now().Minute()) //48
fmt.Println(time.Now().Second()) //46
/*
3. 格式化输出时间
*/
fmt.Println()
fmt.Printf("%02d/%02d/%02d %02d:%02d:%02d",time.Now().Year(),time.Now().Month(),time.Now().Day(),time.Now().Hour(),time.Now().Minute(),time.Now().Second())
/*
4. 这个奇葩的Format格式我也是醉了,2006/01/02 15:04:05这个是当前时间,类似时间戳。
*/
fmt.Println(time.Now().Format("2006/01/02 15:04:05")) //当前时间
fmt.Println(time.Now().Format("01")) //只取当前月
/*
5. 时间常量:
time.Nanosecond //1纳秒
time.Microsecond //1微秒
time.Millisecond //1毫秒
time.Second //1秒
time.Minute //1分钟
time.Hour //1小时
使用方法: 100 * time.Nanosecond //100纳秒
不可以用 time.Microsecond / xx, //只可以用整数*多少,不可以用本身除以多少
*/
time.Sleep(100 * time.Millisecond) //一般结合sleep函数使用,休眠100毫秒
/*
6. time.Unix()和time.UnixNano() 时间戳,后续开发会用到时间戳获取不同的数
*/
fmt.Println(time.Now().Unix()) // 1556901572
fmt.Println(time.Now().UnixNano()) // 1556901572258609400
}
案例1: 编写代码,某一段代码执行的时间
思路分析:主要就是封装一个要测试的函数:
startTime = time.Now().Unix()
test()
endTime = time.Now().Unix()
fmt.Println("代码运行的时长为: ", endTime - startTime)
内置函数
-
len() 用来求长度,比如string(字符为单位),array(元素为单位),slice,map,channel
-
new() 用来分配内存,主要用来分配值类型,返回是一个指针,new中的参数只能是类型,不可以传递数字或者字符串
package main
import "fmt"
func main() {
/*
new(int)都做了什么:首先开辟一块内存空间,存了0进去;开辟了另一块空间,把这个0对应的内存地址当做值存入这个空间,然后num作为指针变量指向0对应的内存地址
*/
num := new(int)
fmt.Printf("num数据类型为%T,num的地址为%v,num的值为%v,*num的值为%v\n",num,&num,num,*num)
*num = 100
fmt.Printf("num数据类型为%T,num的地址为%v,num的值为%v,*num的值为%v",num,&num,num,*num)
/*
num数据类型为*int,num的地址为0xc000082018,num的值为0xc000056080,*num的值为0
num数据类型为*int,num的地址为0xc000082018,num的值为0xc000056080,*num的值为100
地址都是系统分配的,不同电脑num的地址和num的值肯定不一样
*/
}
- make() 用来分配内存,主要用来分配引用类型,channel,map,slice,这些都没学,后续再总结笔记
异常处理
目的: 一旦出现异常程序就崩溃,不会向下执行;异常处理是为了出错后能捕捉或者处理错误,让程序继续向下执行,而不会因为这一个错误导致整个程序崩溃。
python: try except finally
java: try catch finally
Go异常处理:
使用 defer + recover() + panic
Go可以抛出一个panic异常,在defer中使用recover()捕获这个异常。
package main
import (
"fmt"
)
func test() {
/*
使用匿名函数,可以打印err具体信息,还能继续执行代码,增加了代码的健壮性
*/
defer func() {
if err := recover() ; err != nil {
fmt.Printf("发现错误,错误具体信息为%v",err)
//预警机制:反馈错误信息等
fmt.Println("发送给系统管理员")
}
}()
num1 := 10
num2 := 0
res := num1/num2
fmt.Println(res)
}
func main() {
test()
fmt.Println("\n检测上面的代码是不是发生错误这一条也可以打印")
}
自定义错误
可以使用errors.New()和panic内置函数
- errors.New(“错误说明”) 支持自定义错误,创造一个 err error 类型的错误,后面使用panic(err),panic会call出"错误说明"的内容。
- panic内置函数,接受一个interface类型的值作为参数,接受error的变量,输出错误信息,并退出程序。
如何深刻理解error类型的错误:
Linux Shell中 echo $?,上一条命令执行成功则 $?0,Go中nil就是0,error0则程序无异常,error不为0则程序直接终止。
package main
import (
"errors"
"fmt"
)
func readConf (conf string) (err error) {
if conf == "my.conf" {
return nil
} else {
return errors.New("读取文件错误,请重新输入") //error.New()是增加文本panic类型,需要配合panic使用
}
}
func main() {
/*
需求:将配置文件传入,如果配置文件名字不为指定值,则抛出异常,如果为指定值则正常执行程序
*/
err := readConf("shit" )
if err != nil {
panic(err)
}
fmt.Println("看到此句则证明 err==nil")
}