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中从下标 startindexendindex-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)