buildin



1.new

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import (
"fmt"
)

func main() {

num1 := 100
fmt.Printf("num1的类型%T , num1的值=%v , num1的地址%v\n", num1, num1, &num1)

num2 := new(int) // *int
//num2的类型%T => *int
//num2的值 = 地址 0xc04204c098 (这个地址是系统分配)
//num2的地址%v = 地址 0xc04206a020 (这个地址是系统分配)
//num2指向的值 = 100
*num2 = 100
fmt.Printf("num2的类型%T , num2的值=%v , num2的地址%v\n num2这个指针,指向的值=%v",
num2, num2, &num2, *num2)
}

上面代码对应的内存分析图:

go语言new函数



2.异常处理

看一段代码,因此错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (){
"fmt"
}

func test(){
num1 := 10
num2 := 0
res := num1 / num2
fmt.Println("res=",res)
}

func main(){

//测试
test()
fmt.Println("main()下面的代码...")
}

3.对上面的代码总结

  1. 在默认情况下,当发生错误后(panic) ,程序就会退出(崩溃.)

  2. 如果我们希望:当发生错误后,可以捕获到错误,并进行处理,保证程序可以继续执行。还可

以在捕获到错误后,给管理员一个提示(邮件,短信。。。)

  1. 这里引出我们要将的错误处理机制


4.基本说明

  1. Go 语言追求简洁优雅,所以,Go 语言不支持传统的 try…catch…finally 这种处理。
  2. Go 中引入的处理方式为:defer, panic, recover
  3. 这几个异常的使用场景可以这么简单描述:Go 中可以抛出一个 panic 的异常,然后在 defer 中

通过 recover 捕获这个异常,然后正常处理

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
package main
import (
"fmt"
"time"
)

func test(){
// 使用defer + recover 来捕获异常
defer func (){
err := recover()//recover()内置函数,可以捕获到异常
if err !=nil {
fmt.Println("err="err)
}
}()

num1 := 10
num2 := 0
res := num1 /num2
fmt.Println("res=",res)
}

func main(){
//测试
test()
for {
fmt.Println("main()下面的代码...")
time.Sleep(time.Second)
}
}


5.错误处理的好处

进行错误处理后,程序不会轻易挂掉,如果加入预警代码,就可以让程序更加的健壮。看一个

案例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func test() {
//使用defer + recover 来捕获和处理异常
defer func() {
err := recover() // recover()内置函数,可以捕获到异常
if err != nil { // 说明捕获到错误
fmt.Println("err=", err)
//这里就可以将错误信息发送给管理员....
fmt.Println("发送邮件给admin@sohu.com~")
}
}()
num1 := 10
num2 := 0
res := num1 / num2
fmt.Println("res=", res)
}


6.自定义错误

Go 程序中,也支持自定义错误, 使用 errors.New 和 panic 内置函数。

  1. errors.New(“错误说明”) , 会返回一个 error 类型的值,表示一个错误
  2. panic 内置函数 ,接收一个 interface{}类型的值(也就是任何值了)作为参数。可以接收 error 类
    型的变量, 输出错误信息, 并退出程序.

案例代码说明:

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
//函数去读取以配置文件init.conf的信息
//如果文件名传入不正确,我们就返回一个自定义的错误
func readConf(name string) (err error) {
if name == "config.ini" {
//读取...
return nil
} else {
//返回一个自定义错误
return errors.New("读取文件错误..")
}
}

func test02() {

err := readConf("config2.ini")
if err != nil {
//如果读取文件发送错误,就输出这个错误,并终止程序
panic(err)
}
fmt.Println("test02()继续执行....")
}


func main() {

//测试
// test()
// for {
// fmt.Println("main()下面的代码...")
// time.Sleep(time.Second)
// }

//测试自定义错误的使用

test02()
fmt.Println("main()下面的代码...")
}