1、指针
Go 拥有指针。指针保存了值的内存地址
类型 *T
是指向 T
类型值的指针。其零值为 nil。
&
操作符会生成一个指向其操作数的指针
*
操作符表示指针指向的底层值
package main import "fmt" func main() { i := 1 p := &i fmt.Println(p) fmt.Println(*p) }
结果为:
0xc420080008
1
2、结构体Struct
type Person struct { name string age int sex int address string }
go语言中的结构体,类似于java中的实体类,同样Person需要首字母大写,不然实体类没办法调用不是?但是go的结构体就是一个字段的集合。
我们的java是通过new 一个构造器,同样,go也很类似
package main import ( "fmt" ) type Person struct { name string age int sex int address string } func main() { person := Person{"mujiutian",18,1,"北京"} fmt.Println(person) }
输出结果为:
{mujiutian 18 1 北京}
3、结构体指针
结构体字段可以通过结构体指针来访问,如果我们有一个指向结构体的指针 p
,那么可以通过 (*p).X
来访问其字段 X
。不过这么写太啰嗦了,所以语言也允许我们使用隐式间接引用,直接写 p.X
就可以
package main import ( "fmt" ) type Person struct { name string age int sex int address string } func main() { person := Person{"mujiutian",18,1,"北京"} person1 := &person fmt.Println((*person1).address) fmt.Println(person1.address) }
结果为:
北京
北京
4、数组
先说下java的创建数组的方式
int[] a = new int[10];
int[] b = new int[]{1,2,3,45};
然后在重新比较下go创建数组的方式
var a [10]int
var b = [4]int{1,2,3,45}
我们在java10的版本中也同样引入了var的数据类型,其实都是大同小异的,给人感觉颠倒了一样
5、切片
切片给我的理解就是数组的升级版,因为数组大小固定的,而切片是动态增加的,类似于java中的String 和StringBuffer StringBuilder一样,切片运用的更多,不需要用它来指定大小
第一个就是数组,有固定大小,第二个没有设置固定大小,我们称为切片
q := [6]int{2, 3, 5, 7, 11, 13} p := []int{2,3,5,7,11,13}
切片下界的默认值为 0
,上界则是该切片的长度。下界0就是我们java中的0坐标索引index,上界则是该切片的长度
5.1 nil 切片
切片的零值是 nil
。nil 切片的长度和容量为 0 且没有底层数组。
func main() { var s []int fmt.Println(s, len(s), cap(s)) if s == nil { fmt.Println("nil!") } }
结果为:
[] 0 0
nil!
5.2 用make创建切片
切片可以用内建函数 make
来创建,这也是你创建动态数组的方式,make 函数会分配一个元素为零值的数组并返回一个引用了它的切片
a := make([]int, 5) // len(a)=5
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
5.3 切片追加元素
当切片容量达到一定限度的时候,不足以容纳所有给定的值时,它就会分配一个更大的数组。返回的切片会指向这个新分配的数组。这好像和java一个集合原理类似,当长度一定后,创建一个新的更大的数组,然后将它指向新数组。
func printSlice(s []int) { fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) } func main() { var s []int printSlice(s) s = append(s, 0) printSlice(s) s = append(s, 1) printSlice(s) s = append(s, 2, 3, 4) printSlice(s) }
结果为:
len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]
append
的第一个参数 s
是一个元素类型为 T
的切片,其余类型为 T
的值将会追加到该切片的末尾。append
的结果是一个包含原切片所有元素加上新添加元素的切片。
6、Range
for
循环的 range
形式可遍历切片或映射。当使用 for
循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
结果为:
2**0 = 1
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128
可以将下标或值赋予 _
来忽略它。
若你只需要索引,去掉 , value
的部分即可。
for _, value := range pow { fmt.Printf("%d\n", value) }