1. package main
    2. import (
    3. "fmt"
    4. "strings"
    5. )
    6. func main() {
    7. /*
    8. 测试指针使用
    9. */
    10. i, j := 42, 2701
    11. p := &i
    12. fmt.Println(*p)
    13. *p = 21
    14. fmt.Println(i) // 修改了i的值,说明确实指向的是地址
    15. p = &j
    16. *p = *p / 37
    17. fmt.Println(j == *p) // 返回值是true,说明确实修改的是地址
    18. /*
    19. 测试结构体的使用,打印结果:{1 2}
    20. */
    21. fmt.Println(Vertex{1, 2})
    22. //访问结构体字段
    23. v := Vertex{4, 5}
    24. fmt.Println(v.X * v.Y)
    25. //结构体指针 (其实就是为了可以改变结构体里的值)
    26. pp := &v //居然不能用上面的p来直接等于该地址
    27. (*pp).X = 12345
    28. pp.Y = 67890 //两种引用方式
    29. fmt.Println(v)
    30. //结构体的各种缺省赋值
    31. w := Vertex{1, 0}
    32. ww := Vertex{X: 1}
    33. www := Vertex{}
    34. pp = &Vertex{0, 0}
    35. fmt.Println(w == ww, www == *pp, pp) //都是true,所以w,ww这些都是比较的值吗,确实,因为输出的都是数组似的
    36. // 创建结构体类型的指针
    37. ptr := &Vertex{2, 4}
    38. ptr.X = 3
    39. fmt.Println(ptr, ptr.X == 3, ptr.Y)
    40. fmt.Println(v1, v2, p) //{1 2} {0 2} 0xc0000b0070 访问到TestStruct那一层的指针地址
    41. fmt.Println(v11, v22, pp) //{1 2} {0 2} &{0 0}
    42. /*
    43. 数组,定义了长度不可变
    44. */
    45. var arr [12]int
    46. for i := 0; i < 12; i++ {
    47. arr[i] = i
    48. fmt.Print(arr[i], " ")
    49. }
    50. primes := []int{0, 1, 2, 3, 4, 5, 6} //这里是否一定要指明长度? 这样不指明长度是切片写法,指创建了一个数组,构建了一个引用该数组的切片
    51. fmt.Println(primes)
    52. /*
    53. 切片:半开区间 切片不存储任何数据,只是描述了底层数组中的一段 共享改变
    54. len代表元素的个数,cap代表容量
    55. 长度所指向数组中的元素个数
    56. 容量是指切片第一个元素到底层数组元素最后一个元素的个数
    57. append方法,如果切片的底层数组不能容纳切片所有给定值时,切片会分配一个更大容量的数组,返回的切片会指向这个新数组
    58. */
    59. var slice []int = primes[2:5] // primes[2:5]就创建了一个切片
    60. fmt.Println(slice, len(slice), cap(slice)) //output: [2 3 4] 3 5
    61. //slice bounds out of range
    62. // slice = primes[99:100]
    63. slice = primes[6:7]
    64. fmt.Println(slice) //output: [6]
    65. // 可以缺省上下界
    66. slice = primes[:]
    67. fmt.Println(slice, len(slice), cap(slice))
    68. // 空的切片
    69. var emptySlice []int // 这个未定义长度的就是切片。其零值是nil,其无底层数组
    70. fmt.Println(emptySlice, len(emptySlice), cap(emptySlice)) //emptyS[0]是错误写法 ,其零值是 nil
    71. if emptySlice == nil {
    72. fmt.Println("nil")
    73. }
    74. // 空的数组
    75. var emptyArray [0]int
    76. fmt.Println(emptyArray)
    77. // if emptyArray[0]==0{ 这个也不能说去访问emptyArray[0],但我不清楚在底层是否有实际数组
    78. // fmt.Println("0")
    79. // }
    80. // make 创建切片 make 函数会分配一个元素为零值的数组并返回一个引用了它的切片
    81. makeSlice := make([]int, 6) //指定长度
    82. fmt.Println(makeSlice, len(makeSlice), cap(makeSlice))
    83. makeSlice1 := make([]int, 2, 5) //长度为2 , 容量为 5
    84. fmt.Println(makeSlice1, len(makeSlice1), cap(makeSlice1)) // [0 0] 2 5
    85. makeSlice1 = makeSlice1[:cap(makeSlice1)]
    86. fmt.Println(makeSlice1, len(makeSlice1), cap(makeSlice1))
    87. makeSlice1 = makeSlice1[1:]
    88. fmt.Println(makeSlice1, len(makeSlice1), cap(makeSlice1))
    89. // 切片的切片 (二维)
    90. board := [][]string{
    91. []string{"_", "_", "_"},
    92. []string{"_", "_", "_"},
    93. []string{"_", "_", "_"},
    94. }
    95. board[0][0] = "x"
    96. board[0][1] = "o"
    97. board[1][0] = "x"
    98. board[2][0] = "o"
    99. board[1][1] = "x"
    100. board[2][2] = "o"
    101. for i := 0; i < len(board); i++ {
    102. fmt.Printf("%s\n", strings.Join(board[i], " "))
    103. }
    104. //Range 使用for循环遍历切片时候,每次迭代都会返回两个值,第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本
    105. for i, j := range board {
    106. for m, n := range j {
    107. fmt.Println("board[", i, " ", m, "]", n)
    108. }
    109. }
    110. //Range 使用时可以忽略其 下标或下标所对应元素的副本
    111. for i := range board {
    112. fmt.Printf("%d ", i)
    113. }
    114. for _, j := range board {
    115. fmt.Println(j)
    116. }
    117. for i := range board {
    118. fmt.Println(i)
    119. }
    120. //映射 make函数会返回给定类型的映射,并将其初始化备用
    121. var m map[string]Vertex = make(map[string]Vertex) //make也可以用在键值对的映射里面
    122. m["Bell Labs"] = Vertex{1, 2}
    123. fmt.Println(m["Bell Labs"])
    124. //多个映射
    125. var mm = map[string]Vertex{
    126. "Bell Labs": Vertex{1, 2},
    127. "Google": Vertex{3, 4},
    128. }
    129. fmt.Println(mm)
    130. var mmm = map[int]Vertex{
    131. 1: {1, 2},
    132. 2: {3, 4}, //可以省略掉类型
    133. }
    134. fmt.Println(mmm)
    135. for _, j := range mmm {
    136. fmt.Println(j)
    137. }
    138. //在映射m中插入或修改元素
    139. ss := make(map[string]int)
    140. ss["answer"]=42
    141. fmt.Println("the value",ss["answer"])
    142. ss["answer"]=48
    143. fmt.Println("the value",ss["answer"])
    144. delete(ss,"answer")
    145. fmt.Println("the value",ss["answer"])
    146. elem,ok := ss["answer"]
    147. fmt.Println(elem,ok) // 0,false elem 没在 m中返回 false
    148. ss["yes"]=2
    149. elem,ok = ss["yes"]
    150. fmt.Println(elem,ok) //2,true elme 在 m 中,所以返回其elme 值,并ok为true
    151. // strings.Fields方法可以切分字符串
    152. var str = make(map[string]int)
    153. var s = "This is a test,but is not noly a test"
    154. var c = strings.Fields(s)
    155. for _,j := range c {
    156. str[j] ++
    157. }
    158. fmt.Println(str)
    159. }
    160. // Vertex 是结构体
    161. type Vertex struct {
    162. X int
    163. Y int
    164. }
    165. //TestStruct 使用结构体文法通过直接列出字段的值来分配一个结构体
    166. type TestStruct struct {
    167. x, y int //非导出字段,不可从包外面访问。类似不可以从该结构体外面访问?
    168. }
    169. //TestPipeStruct 测试导出字段的结构体(与上面相对应)
    170. type TestPipeStruct struct {
    171. X, Y int
    172. }
    173. var (
    174. v1 = TestStruct{1, 2}
    175. v2 = TestStruct{y: 2}
    176. p = &TestStruct{1, 2}
    177. )
    178. var (
    179. v11 = TestPipeStruct{1, 2}
    180. v22 = TestPipeStruct{Y: 2}
    181. pp = &TestPipeStruct{1, 2}
    182. )