1. 数组与切片

  • 定义 ```go var a [3]int //数组 var a []int //切片

b := [3]int{1,2,3} //数组 c := […]int{1,2,3} //数组 b := []int{1,2,3} //切片

  1. 数组需要指定长度或用 `...` 表示长度,切片定义不指定长度。
  2. - **遍历**
  3. ```go
  4. func TestArrayTravel(t *testing.T) {
  5. arr := [...]int{1, 2, 3, 4, 5}
  6. slice := []int{1, 2, 3, 4, 5}
  7. for i := 0; i < len(arr); i++ {
  8. t.Log(arr[i])
  9. t.Log(slice[i])
  10. }
  11. for idx, e := range arr {
  12. t.Log(idx, e)
  13. }
  14. for idx, e := range arr {
  15. t.Log(idx, e)
  16. }
  17. for idx, e := range slice {
  18. t.Log(idx, e)
  19. }
  20. for _, e := range arr {
  21. t.Log(e)
  22. }
  23. for _, e := range slice {
  24. t.Log(e)
  25. }
  26. }

切片与数组在遍历特征上没有任何差别有三种遍历方式:

  • for i 使用下表访问
  • for idx,e : range 迭代访问下标和元素
  • for _,e : range 迭代仅访问元素
    • 截取 ```go func TestArrayCult(t *testing.T) { arr := […]int{1, 2, 3, 4, 5} arr1 := arr[:3] t.Log(arr1) arr1 = arr[1:3] arr1 = append(arr1, 99) t.Log(arr1, arr) arr1 = arr[1:] t.Log(arr1) arr1 = arr[1:len(arr)] t.Log(arr1) arr1[0] = 100 t.Log(arr, arr1) } === RUN TestArrayCult TestArrayCult: array_test.go:47: [1 2 3] TestArrayCult: array_test.go:50: [2 3 99] [1 2 3 99 5] TestArrayCult: array_test.go:52: [2 3 99 5] TestArrayCult: array_test.go:54: [2 3 99 5] TestArrayCult: array_test.go:56: [1 100 3 99 5] [100 3 99 5] —- PASS: TestArrayCult (0.00s) PASS

// slice的内存共享 func TestSliceShareMemory(t *testing.T) { year := []string{“Jab”, “Feb”, “Mar”, “Apr”, “May”, “Jun”, “Jul”, “Aug”, “Sep”, “Oct”, “Nov”, “Dec”} Q2 := year[3:6] t.Log(Q2, len(Q2), cap(Q2))

  1. summer := year[5:8]
  2. t.Log(summer, len(summer), cap(summer), year[8])
  3. summer = append(summer, "what?")
  4. t.Log(summer, len(summer), cap(summer), year[8])
  5. summer[0] = "Unknown"
  6. t.Log(Q2)
  7. t.Log(year)

} === RUN TestSliceShareMemory TestSliceShareMemory: slice_test.go:36: [Apr May Jun] 3 9 TestSliceShareMemory: slice_test.go:38: [Jun Jul Aug] 3 7 Sep TestSliceShareMemory: slice_test.go:40: [Jun Jul Aug what?] 4 7 what? TestSliceShareMemory: slice_test.go:43: [Apr May Unknown] TestSliceShareMemory: slice_test.go:44: [Jab Feb Mar Apr May Unknown Jul Aug what? Oct Nov Dec] —- PASS: TestSliceShareMemory (0.00s) PASS

  1. - 采用 `a[n,m]` 方式截取,n包含,m不包含
  2. - nm可省略,表示从头开始或者截取到末尾
  3. - 截取后的存储空间是共享的,capacity为截取始点所有原切片的长度
  4. - 修改截取后的数据会影响原数组/切片
  5. - append数组/切片后会覆盖原切片/切片的后面的值
  6. - **Array Slice 的差异**
  7. **![image.png](https://cdn.nlark.com/yuque/0/2020/png/1732425/1595773658480-9b22f703-4a79-4c1b-84fa-e989c503e20d.png#align=left&display=inline&height=323&margin=%5Bobject%20Object%5D&name=image.png&originHeight=430&originWidth=867&size=56895&status=done&style=none&width=650)**<br />**![image.png](https://cdn.nlark.com/yuque/0/2020/png/1732425/1595773493359-e9e665f7-9847-4fcc-a2bd-f1d6ee14f881.png#align=left&display=inline&height=176&margin=%5Bobject%20Object%5D&name=image.png&originHeight=234&originWidth=853&size=25135&status=done&style=none&width=640)**<br />**![image.png](https://cdn.nlark.com/yuque/0/2020/png/1732425/1595773608762-9bd18cf3-3bb7-49a2-a90e-13181ccafb36.png#align=left&display=inline&height=564&margin=%5Bobject%20Object%5D&name=image.png&originHeight=564&originWidth=615&size=71130&status=done&style=none&width=615)**
  8. **
  9. - Slice定义时不指定长度为可变数组
  10. - Slice的数据结构为`(*ptr,len,cap)`
  11. - Slice不可比较
  12. - Slicecapacity拓展每次增加一倍
  13. <a name="IlEb2"></a>
  14. ## 2. Map
  15. ```go
  16. func TestMap(t *testing.T) {
  17. // map[keyType]valueType
  18. m1 := map[string]int{"one": 1, "two": 2, "three": 3}
  19. t.Log(m1)
  20. t.Log(m1["three"])
  21. // key 不存在时返回默认初始化值
  22. t.Log(m1["four"])
  23. // 通过一次性给两个变量赋值,确定map中的元素是否存在
  24. if v, ok := m1["four"]; ok {
  25. t.Logf("exits four is %d", v)
  26. } else {
  27. t.Log("four is not exits")
  28. }
  29. //遍历
  30. for k, v := range m1 {
  31. t.Logf("(%s,%d)", k, v)
  32. }
  33. // make(type,capacity)
  34. m2 := make(map[string]string, 16)
  35. t.Log(m2)
  36. }
  37. // map的值类型可以是方法,实现工厂模式
  38. func TestMapWithFunction(t *testing.T) {
  39. // 值类型为 func(op int) int
  40. fund := map[int]func(op int) int{}
  41. fund[1] = func(op int) int {
  42. return op
  43. }
  44. fund[2] = func(op int) int { return op * op }
  45. fund[3] = func(op int) int { return op * op * op }
  46. for _, v := range fund {
  47. t.Log(v(2))
  48. }
  49. }
  50. // map 实现set,利用不存在的value会被初始化为默认值false
  51. func TestMapForSet(t *testing.T) {
  52. mySet := map[int]bool{}
  53. mySet[1] = true
  54. mySet[3] = true
  55. // 判断元素是否存在
  56. existsTest(t, 3, mySet)
  57. // 判断长度
  58. t.Log(len(mySet))
  59. // 删除
  60. delete(mySet, 1)
  61. t.Log(len(mySet))
  62. existsTest(t, 1, mySet)
  63. }
  64. // 注意这种实现set的方式,不要手动的放置false值,否则产生了语义冲突
  65. // 判断元素是否存在
  66. func existsTest(t *testing.T, n int, mySet map[int]bool) {
  67. if mySet[n] {
  68. t.Logf("%d is exists", n)
  69. } else {
  70. t.Logf("%d is not exists", n)
  71. }
  72. }

3. String

  1. // 字符串测试
  2. func TestString(t *testing.T) {
  3. var s string
  4. t.Log(s)
  5. s = "hello 中国"
  6. c := []rune(s)
  7. t.Logf("字符串的字节数:%d, 字符数:%d", len(s), len(c))
  8. for _, v := range s {
  9. t.Logf("char:%[1]c, unicode:%[1]d,%[1]x", v)
  10. }
  11. }
  12. // 字符串转换测试
  13. func TestString2(t *testing.T) {
  14. s := "A,B,C"
  15. parts := strings.Split(s, ",")
  16. for _, part := range parts {
  17. t.Log(part)
  18. }
  19. t.Log(strings.Join(parts, "-"))
  20. ts := strconv.Itoa(10)
  21. t.Log("str" + ts)
  22. if i, err := strconv.Atoi(ts); err == nil {
  23. t.Log(10 + i)
  24. }
  25. }