demo1. defer用法

  1. func DeferCall() {
  2. defer func() { fmt.Println("打印前") }()
  3. defer func() { fmt.Println("打印中") }()
  4. defer func() { fmt.Println("打印后") }()
  5. panic("触发异常")
  6. defer func() { fmt.Println("121") }() // 执行不到
  7. }
  8. // OUT:
  9. 打印后
  10. 打印中
  11. 打印前
  12. panic: 触发异常
  13. // 解析:
  14. defer的执行顺序是先进后出。当出现panic语句时,会先按照defer的先进后出的顺序执行,最后才会执行panic

demo2. for循环时创建每个元素的副本,注意指针类型数据

  1. func PointerTest() {
  2. slice := []int{0, 1, 2, 3}
  3. m := make(map[int]*int)
  4. for key, val := range slice {
  5. //temp := val
  6. m[key] = &val
  7. }
  8. for k, v := range m {
  9. fmt.Println(k, "->", *v)
  10. }
  11. }
  12. // OUT:
  13. 0 -> 3
  14. 1 -> 3
  15. 2 -> 3
  16. 3 -> 3
  17. // 解析:
  18. for range 循环时会创建每个元素的副本,而不是元素的引用,所以 m[key]=&val 取的都是变量val的地址,所以最后map中的所有元素的值都是变量val的地址,因为最后val被赋值为3,所有输出都是3
  19. // 修改:
  20. temp := val
  21. m[key] = &temp

demo3. new和make的区别

  1. //Test31 is a function
  2. func Test31() {
  3. s := make([]int, 5)
  4. s = append(s, 1, 2, 3)
  5. fmt.Println(s)
  6. }
  7. //Test32 is a function
  8. func Test32() {
  9. s := make([]int, 0)
  10. s = append(s, 1, 2, 3, 4)
  11. fmt.Println(s)
  12. }
  13. //FuncMui is a function
  14. func FuncMui(x, y int) (sum int, error) {
  15. return (x + y), nil
  16. }
  17. //阐述new与make的区别
  18. // OUT:
  19. [0 0 0 0 0 1 2 3]
  20. [1 2 3 4]
  21. syntax error: mixed named and unnamed function parameters
  22. // 解析:
  23. 1make定义切片时,初始化了切片的长度为5,默认值为0
  24. 2、第二个返回值没有命名
  25. 在函数有多个返回值时,情况如下:
  26. 只要有一个返回值有命名,其他的也必须命令。
  27. 如果有多个返回值必须加上括号()。
  28. 如果只有一个返回值且命名也必须加上括号()。
  29. 这里的第一个返回值有命名sum,第二个没有命名,所以出现语法错误
  30. 3new(T)和make(T,args)是go语言内建函数,用来分配内存,但适用的类型不同:
  31. new(T)会为T类型的新值分配已置零的内存空间,并返回地址(指针),即类型为*T的值,换句话说,返回一个指针,该指针指向新分配的,类型为T的零值。适用于值类型,如数组、结构体等。
  32. make(T,args)返回初始化后的T类型的值,这个值并不是T类型的零值,也不是指针*T,是经过初始化之后的T的引用。make()只适用于slicemapchanael

demo4. 下列程序是否能够通过编译

  1. // 第1题
  2. func Test41() {
  3. list := new([]int)
  4. list = append(list,1)
  5. fmt.Println(list)
  6. }
  7. // 第2题
  8. func Test42() {
  9. s1 := []int{1,2,3}
  10. s2 := []int{4,5}
  11. s1 = append(s1,s2)
  12. fmt.Println(s1)
  13. }
  14. // 第3题
  15. var(
  16. size := 1024
  17. max_size := size*2
  18. )
  19. func main () {
  20. fmt.Println(size, max_size)
  21. }
  22. // OUT:
  23. 1、不能通过编译
  24. new([]int)返回的是一个*[]int类型指针,即list变量是个指针变量,不能对指针执行append操作。可以使用make()初始化后再用。
  25. 同样,mapchan建议使用make()或字面量的方式进行初始化,不可用new()。
  26. 2、不能通过编译
  27. append()的第二个参数不能直接使用slice,需使用 ... 操作符,将一个切片追加到另一个切片中:append(s1,s2...),或者直接跟上元素,如:append(s1,1,2,3)。
  28. 3、不能通过编译
  29. 变量声明的简短模式具有限制:
  30. 1)、必须使用显示初始化
  31. 2)、不能提供数据类型,编译器会自动推导
  32. 3)、只能在函数内部使用简短模式

demo5. test

  1. // 第1题
  2. sn1 := struct {
  3. age int
  4. name string
  5. }{ age: 11,name: "qq" }
  6. sn2 := struct {
  7. age int
  8. name string
  9. }{
  10. age: 11,
  11. name: "qq",
  12. }
  13. if sn1 == sn2 {
  14. fmt.Println("sn1 == sn2")
  15. }
  16. // 第 2 题
  17. sm1 := struct {
  18. age int
  19. m map[string]string
  20. }{
  21. age: 11,
  22. m: map[string]string,
  23. }
  24. sm2 := struct {
  25. age int
  26. m map[string]string
  27. }{
  28. age: 11,
  29. m: map[string]string,
  30. }
  31. if sm1 == sm2 {
  32. fmt.Println("sm1 == sm2")
  33. }
  34. // OUT: