Go 函数、 数组、 指针、 结构体、 切片
十、函数
1、格式:
func 函数名(参数列表) 返回值类型{
}
当有多个返回值时:
func 函数名(参数列表) (返回值1类型,返回值2类型,返回值3类型){
}
2、函数参数
x *int
3、函数作为实参
例:
//声明函数变量
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* 使用函数 */
fmt.Println(getSquareRoot(9))
4、闭包(匿名函数)
例:
func get1() func() int {
i :=0
return func() int {
i++
return i
}
}
func get2(x,y int) func(a,b int) (int,int){
return func(a, b int) (int, int) {
return x+y,a+b
}
}
func main(){
nextNum := get1()
println(nextNum())
sumNum := get2(1,2)
println(sumNum(3,4))
}
5、方法
Go 语言中同时有 函数 和 方法 。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。
格式:
func (variable_name variable_data_type) function_name() [return_type]{
/* 函数体*/
}
例:
type Circle struct {
radius float64
}
func (c Circle) area() float64 {
return 3.14*c.radius*c.radius
}
func main(){
var c1 Circle
c1.radius=10
println(c1.area())
}
十一、变量作用域
十二、数组
1、格式
var 数组名 [数组大小] 数据类型
var a [10] int
2、初始化
例:
var a = [3]int{1,2,3}
//或者
a := [3]int{1,2,3}
(1)如果数组长度不确定,可以使用 … 代替数组的长度,编译器会根据元素个数自行推断数组的长度
var a = [...]int{1,2,3,4,5}
(2)如果设置了数组的长度,还可以通过指定下标来初始化元素
// 将索引为 1 和 3 的元素初始化
a := [5]float32{1:2.0,3:7.0}
2、多维数组
var 数组名 [1维数组大小][2维数组大小]...[n维数组大小] 数据类型
var a [2][3]int
3、实例
//数组
var a [5]int
for i :=0;i<5;i++ {
a[i]=i+1
}
for j :=0;j<5;j++ {
println(a[j])
}
b1 := [3]float32{1.0,2.0,3.0}
for i :=0;i<3;i++ {
println(b1[i])
}
b2 := [...]int{1,2,3}
for j :=0;j<3;j++ {
println(b2[j])
}
b3 := [5]int{0:2,3:6}
for k :=0; k<5;k++ {
println(b3[k])
}
//二维数组
values := [][]int{}
row1 := []int{1,2,3}
row2 := []int{4,5,6}
values = append(values, row1)
values = append(values,row2)
fmt.Println("Row1:",values[0])
fmt.Println("Row2:",values[1])
fmt.Println("第一个元素是:",values[0][0])
a := [3][4]int{
{0, 1, 2, 3} , /* 第一行索引为 0 */
{4, 5, 6, 7} , /* 第二行索引为 1 */
{8, 9, 10, 11}, /* 第三行索引为 2 */
}
fmt.Println(a[0])
str := [2][2]string{}
str[0][0] ="a"
str[1][1] ="b"
fmt.Println(str)
animals := [][]string{}
row1 := []string{"dog","cat","fish"}
row2 := []string{"bird","shark"}
row3 := []string{"sheep"}
animals =append(animals,row1)
animals =append(animals,row3)
animals =append(animals,row2)
for i := range animals{
fmt.Println(animals[i])
}
十三、指针
格式:
var 指针名 *指针类型
1、空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil,nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值
2、例:
var ptr *int
var a int = 10
ptr = &a
3、指针数组
格式:
var 指针名 [指针大小]*指针类型
4、指向指针的指针
格式:
var 指针名 **指针类型
十四、结构体
1、结构体
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合
格式:
type 结构体名字 struct{
变量名 变量类型
...
变量名 变量类型
}
2、定义结构体类型变量
var 变量名 结构体名字
或
变量名 := 结构体名字{value1,value2,...,valuen}
或
变量名 := 结构体名字{key1:value1,key2:value2,...,keyn:valuen}
3、给结构体内的变量赋值
结构体变量名.结构体内部变量 = 值
4、实例
type Book struct {
ID int
name string
price float32
}
func main(){
//结构体
fmt.Println(Book{1,"java",32.5})
fmt.Println(Book{ID: 2,name: "c语言",price: 40.5})
var book Book
book.ID = 3
book.name = "Go语言"
book.price = 29.9
fmt.Println("ID:",book.ID,"name:",book.name,"price:",book.price)
}
十五、切片(Slice)
1、切片
切片是对数组的抽象。切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
定义切片:
声明一个未指定大小的数组来定义切片,切片不需要说明长度
var 切片名 []变量类型
或使用 make() 函数来创建切片,len是数组的长度,也是切片的初始长度
var 切片名 []变量类型 = make([]变量类型,len)
也可以简写成 :
切片名 := make([]变量类型,len)
也可以指定容量,其中 capacity 为可选参数
make([]T,len,capacity)
2、初始化
(1)直接初始化切片,[]表示切片类型,{1,2,3}初始化初值依次是1,2,3,其中cap=len=3
s :=[] int{1,2,3}
(2)初始化切片s,是数组 arr 的引用
s := arr[:]
(3)将arr中从下标 startindex 到 endindex-1 下的元素创建为一个新的切片
s := arr[startindex:endindex]
(4)默认 endindex 时将表示一直到 arr 的最后一个元素
s := arr[startindex:]
(5)默认 startindex 时将表示从 arr 的第一个元素开始
s := arr[:endindex]
(6)通过切片 s 初始化切片 s1
s1 := s[startindex:endindex]
(7)通过内置函数 make() 初始化切片s
s :=make([]int,len,cap)
3、len() 和 cap() 函数
切片是可索引的,并且可以由len()方法获取长度
切片提供了计算容量的方法cap()可以测量切片最长可以达到多少
4、空(nil)切片
一个切片在未初始化之前默认为nil,长度为0
5、通过设置下限及上限来设置截取切片
如:
numbers[1:4] //切片从索引1到索引4(不包含)
6、append() 和 copy() 函数
如果想增加切片的容量,必须创建一个新的更大的切片并把原分片的内容都拷贝过来
var nums []int //定义切片
nums=append(nums,1) //向切片nums中追加元素1
nums=append(nums,2,3,4) //向切片nums中追加元素2,3,4
nums1 :=make([]int,len(nums),(cap(nums))*2) //新建一个切片,
copy(nums1,nums) //将nums切片复制给nums1
7、实例
//切片
var s =make([]int,3,6)
fmt.Printf("len=%d cap=%d slice=%v \n",len(s),cap(s),s)
var num []int
if(num == nil){
fmt.Println("切片是空的")
}
numbers := []int{0,1,2,3,4,5,6,7,8,9}
fmt.Println("numbers ==",numbers)
fmt.Println("numbers[1:4] ==",numbers[1:4])
fmt.Println("numbers[:3] ==",numbers[:3])
fmt.Println("numbers[3:] ==",numbers[3:])
var nums []int
fmt.Printf("len=%d cap=%d slice=%v \n",len(nums),cap(nums),nums)
nums=append(nums,1)
fmt.Printf("len=%d cap=%d slice=%v \n",len(nums),cap(nums),nums)
nums=append(nums,2,3,4)
fmt.Printf("len=%d cap=%d slice=%v \n",len(nums),cap(nums),nums)
nums1 :=make([]int,len(nums),(cap(nums))*2)
copy(nums1,nums)
fmt.Printf("len=%d cap=%d slice=%v \n",len(nums1),cap(nums1),nums1)