[Go] Range 探討

程式語言:Go
官網定義

簡介:Range 探討

range 會在執行 for 之前,被完整的執行過一次
也就是拆開的結果會被存在另一個變數中,再依序此變數執行 for 內的動作
但此變數是值還是位址,取決於不同的類型
而這只是通則,不適用在 map 上
Range expression                          1st value          2nd value

array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E
string          s  string type            index    i  int    see below  rune
map             m  map[K]V                key      k  K      m[k]       V
channel         c  chan E, <-chan E       element  e  E

程式碼

array
取決是值 or 位址,決定是否會更改值
The Go Playground
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. arr := [5]int{1, 2, 3, 4, 5}
  9. for i, v := range arr {
  10. arr[4] = 100 // 不改值
  11. fmt.Printf("index:%d value:%d type:%T\n", i, v, v)
  12. }
  13. fmt.Println()
  14. for i, v := range &arr {
  15. arr[4] = 100 // 改值
  16. fmt.Printf("index:%d value:%d type:%T\n", i, v, v)
  17. }
  18. }
slice
新增不影響,即使容量事先宣告
但修改值,若曾先 append 過,當原本的 cap 值不夠時,會被重新分配新的底層 array
The Go Playground
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. arr1 := []int{1, 2, 3, 4, 5}
  9. for i, v := range arr1 {
  10. arr1[4] = 100
  11. fmt.Printf("index:%d value:%d type:%T\n", i, v, v)
  12. }
  13. fmt.Println()
  14. arr2 := []int{1, 2, 3, 4, 5}
  15. for i, v := range arr2 {
  16. arr2 = append(arr2, 6)
  17. arr2[4] = 100
  18. fmt.Printf("index:%d value:%d type:%T\n", i, v, v)
  19. }
  20. fmt.Println()
  21. arr3 := make([]int, 5, 10)
  22. arr3[0] = 1
  23. arr3[1] = 2
  24. arr3[2] = 3
  25. arr3[3] = 4
  26. arr3[4] = 5
  27. for i, v := range arr3 {
  28. arr3 = append(arr3, 6)
  29. arr3[4] = 100
  30. fmt.Printf("index:%d value:%d type:%T\n", i, v, v)
  31. }
  32. }
string
不更改值,新增也不影響
The Go Playground
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. str := "12345"
  9. for i, c := range str {
  10. str = "92345678"
  11. fmt.Printf("i:%d v:%c type:%T\n", i, c, c)
  12. }
  13. }
map
可能改值,可能不更改值,取決是否已跑過
可能加入,可能不加入,取決於 buffer,但仍是隨機
The Go Playground
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. m1:= make(map[string]string)
  9.  
  10. m1["1"] = "1"
  11. m1["2"] = "2"
  12. m1["3"] = "3"
  13. m1["4"] = "4"
  14. m1["5"] = "5"
  15. m1["6"] = "6"
  16. for k, v := range m1{
  17. m1["1"] = "100"
  18. m1["6"] = "100"
  19. m1["7"] = "7"
  20. m1["8"] = "8"
  21. m1["9"] = "9"
  22. m1["10"] = "10"
  23. m1["11"] = "11"
  24. m1["12"] = "12"
  25. fmt.Printf("k:%s v:%s type:%T\n", k, v, v)
  26. }
  27. fmt.Println()
  28. m2:= make(map[string]string,500)
  29.  
  30. m2["1"] = "1"
  31. m2["2"] = "2"
  32. m2["3"] = "3"
  33. m2["4"] = "4"
  34. m2["5"] = "5"
  35. m2["6"] = "6"
  36. for k, v := range m2{
  37. m2["7"] = "7"
  38. m2["8"] = "8"
  39. m2["9"] = "9"
  40. m2["10"] = "10"
  41. m2["11"] = "11"
  42. m2["12"] = "12"
  43. fmt.Printf("k:%s v:%s type:%T\n", k, v, v)
  44. }
  45. }
channel
取決傳入值的性質,決定是否更改值與加入
The Go Playground
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func run(c chan int){
  8. arr := [5]int{1, 2, 3, 4, 5}
  9. for _, v := range arr {
  10. c <- v
  11. }
  12. close(c)
  13. }
  14.  
  15. func main() {
  16. c := make(chan int)
  17. go run(c)
  18. for v := range c{
  19. fmt.Printf("value:%d type:%T\n", v, v)
  20. }
  21. }
The Go Playground
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func run(c chan [5]int){
  8. arr := [5]int{1, 2, 3, 4, 5}
  9. c <- arr
  10. close(c)
  11. }
  12.  
  13. func main() {
  14. c := make(chan [5]int)
  15. go run(c)
  16. for v := range c{
  17. fmt.Printf("value:%d type:%T\n", v, v)
  18. }
  19. }

參考

聊聊Golang中的range关键字

留言