go值传递

  • 值传递? 应用传递?

    在c++ 中:
    Go 基础学习(三) - 图1
    image.gif
    java python 除了基本类型都是引用传递

go 值传递一种方式。都拷贝一份。结合指针传递实现类似引用传递:
Go 基础学习(三) - 图3image.gif
Go 基础学习(三) - 图5image.gif

数组

  • 数组是值类型。方法传递是拷贝。
  • arr [5]int 与 arr[]int 不同,后面的是切片
  • 可以使用指针进行传递
  • go 语言不直接使用数组,使用切片
  1. package main
  2. import "fmt"
  3. //数组循环
  4. func printArray(arr [5]int) {
  5. arr[0] = 100
  6. for i, v := range arr {
  7. fmt.Println(i, v)
  8. }
  9. }
  10. func main() {
  11. //数组定义
  12. var arr1 [5]int
  13. arr2 := [3]int{1, 3, 5}
  14. //... 自动指定个数
  15. arr3 := [...]int{2, 4, 6, 8, 10}
  16. var grid [4][5]int
  17. fmt.Println("array definitions:")
  18. fmt.Println(arr1, arr2, arr3)
  19. fmt.Println(grid)
  20. fmt.Println("printArray(arr1)")
  21. printArray(arr1)
  22. fmt.Println("printArray(arr3)")
  23. printArray(arr3)
  24. fmt.Println("arr1 and arr3")
  25. fmt.Println(arr1, arr3)
  26. }

切片 slice

  • slice是数组的视图
  • 改变(slice)视图中的值。原数组的值也改变
  • 可以对slice1进行slice2。都是对同一个array的视图
  • slice 内部结构。ptr 开始位置,len 当前切片的长度, 原数据从切片的ptr后还有多少元素

Go 基础学习(三) - 图7
Extending slice 。slice 可以扩展的。不能向后扩展,不可以向前扩展
Extending slice 不可以超越len,向后扩展不可以超越底层数组cap

  1. fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))

slice append

append 数据,如果超过cap,系统会重新分配更大的底层数组,原来的数组go会进行垃圾回收
由于值传递,必须接appent的返回值。s3 := append(s2, 10)

  1. package main
  2. import "fmt"
  3. func updateSlice(s []int) {
  4. s[0] = 100
  5. }
  6. func main() {
  7. arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
  8. fmt.Println("arr[2:6] =", arr[2:6])
  9. fmt.Println("arr[:6] =", arr[:6])
  10. s1 := arr[2:]
  11. fmt.Println("s1 =", s1)
  12. s2 := arr[:]
  13. fmt.Println("s2 =", s2)
  14. fmt.Println("After updateSlice(s1)")
  15. updateSlice(s1)
  16. fmt.Println(s1)
  17. fmt.Println(arr)
  18. fmt.Println("After updateSlice(s2)")
  19. updateSlice(s2)
  20. fmt.Println(s2)
  21. fmt.Println(arr)
  22. fmt.Println("Reslice")
  23. fmt.Println(s2)
  24. s2 = s2[:5]
  25. fmt.Println(s2)
  26. s2 = s2[2:]
  27. fmt.Println(s2)
  28. fmt.Println("Extending slice")
  29. arr[0], arr[2] = 0, 2
  30. fmt.Println("arr =", arr)
  31. s1 = arr[2:6]
  32. s2 = s1[3:5] // [s1[3], s1[4]]
  33. fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n",
  34. s1, len(s1), cap(s1))
  35. fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n",
  36. s2, len(s2), cap(s2))
  37. s3 := append(s2, 10)
  38. s4 := append(s3, 11)
  39. s5 := append(s4, 12)
  40. fmt.Println("s3, s4, s5 =", s3, s4, s5)
  41. // s4 and s5 no longer view arr.
  42. fmt.Println("arr =", arr)
  43. // Uncomment to run sliceOps demo.
  44. // If we see undefined: sliceOps
  45. // please try go run slices.go sliceops.go
  46. fmt.Println("Uncomment to see sliceOps demo")
  47. // sliceOps()
  48. }

append 时候如果cap 不够了每次都会扩充cap 的两倍容量

切片操作

  1. package main
  2. import "fmt"
  3. func printSlice(s []int) {
  4. fmt.Printf("%v, len=%d, cap=%d\n",
  5. s, len(s), cap(s))
  6. }
  7. func sliceOps() {
  8. fmt.Println("Creating slice")
  9. var s []int // Zero value for slice is nil
  10. for i := 0; i < 100; i++ {
  11. printSlice(s)
  12. s = append(s, 2*i+1)
  13. }
  14. fmt.Println(s)
  15. //创建了array 并同时创建slice
  16. s1 := []int{2, 4, 6, 8}
  17. printSlice(s1)
  18. //知道多大的slice len(16)
  19. s2 := make([]int, 16)
  20. //len(10) cap(32)
  21. s3 := make([]int, 10, 32)
  22. printSlice(s2)
  23. printSlice(s3)
  24. fmt.Println("Copying slice")
  25. copy(s2, s1)
  26. printSlice(s2)
  27. fmt.Println("Deleting elements from slice")
  28. s2 = append(s2[:3], s2[4:]...)
  29. printSlice(s2)
  30. fmt.Println("Popping from front")
  31. front := s2[0]
  32. s2 = s2[1:]
  33. fmt.Println(front)
  34. printSlice(s2)
  35. fmt.Println("Popping from back")
  36. tail := s2[len(s2)-1]
  37. s2 = s2[:len(s2)-1]
  38. fmt.Println(tail)
  39. printSlice(s2)
  40. }

image.jpeg