Go 数组 slice map type struct

文章目录

  • 数组和slice
  • slice的四种声明方式
  • slice追加与截取
  • map四种声明方式
  • map的一些操作
    • 遍历
    • 删除
    • 函数传参(引用)
  • type
  • struct
    • 结构体对象函数传参

数组和slice

Go里面数组是指指定长度大小的数组。不像C++里面,不指定长度大小也是数组。

arr1 := [10]int
var arr2 = [10]int

数组在go里面,大小不一样,它的类型是不一样。

它们的类型分别是[10]int和[20]int

arr1 := [10]int{1, 2, 3, 4}
var arr2 = [20]int{1, 2, 3, 4}
fmt.Printf("%T\n", arr1)
fmt.Printf("%T\n", arr2)

在这里插入图片描述

数组在函数传参时采用的是传值拷贝。因此函数内部无法改变外部的数组大小。

由于数组大小不同类型也不同,因此函数参数类型必须是[10]int,不能缺少指定大小的数字

固定长度的数组在传参的时候是严格匹配数组类型的
func printarr(myArr [10]int) { //这个参数是拷贝过来的,不是引用, 因为你传的是数组。实际中用切片更多
	for i, v := range myArr {
		fmt.Println("index: ", i, " value: ", v)
	}
	无效操作,没有用
	myArr[0] = 10000
}

slice是切片,只要定义的时候不带上固定大小,那就是slice。

slice的类型就是[]具体类型名

arr1 := []int{1, 2, 3, 4}
var arr2 = []int{1, 2, 3, 4}
fmt.Printf("%T\n", arr1)
fmt.Printf("%T\n", arr2)

在这里插入图片描述

slice在函数传参的时候采用的是传引用,因此内部可以修改外部的slice

slice的类型不能加固定数字,因为slice的类型就是[]int(或者其他)

//指定了大小的就是数组,是拷贝
//没有指定大小的就是切片,是引用
func printslice(myArr []int) {
	for i, v := range myArr {
		fmt.Println("index: ", i, " value: ", v)
	}
	myArr[0] = 10000
}

slice的四种声明方式

//第一种声明方式
slice1 := []int{1, 2, 3}
fmt.Printf("len = %d, slice = %v\n", len(slice1), slice1)

//第二种声明方式,没有分配空间
var slice2 []int
slice2 = make([]int, 3) //make可以为slice2分配空间,默认值为0
fmt.Printf("len = %d, slice = %v\n", len(slice2), slice2)

//第三种声明方式,直接用make
var slice3 = make([]int, 3)
fmt.Printf("len= %d, slice = %v\n", len(slice3), slice3)

//第四种:= + make,一般用这一种
slice4 := make([]int, 3)
fmt.Printf("len= %d, slice = %v\n", len(slice4), slice4)

可以用是否等于nil来判断切片是否为空

var slice5 []int
if slice5 == nil {
	fmt.Println("slice5 是一个空切片")
} else {
	fmt.Println("slice5不是 空切片")
}

Go 数组 slice map type struct_第1张图片

slice追加与截取

slice在这里和vector是一样的。

numbers := make([]int, 3, 5) 3代表size=35代表cap=5
fmt.Printf("len: %d, cap: %d, slice: %v\n", len(numbers), cap(numbers), numbers)

numbers = append(numbers, 3)
numbers = append(numbers, 5)
numbers = append(numbers, 10)
fmt.Printf("len: %d, cap: %d, slice: %v\n", len(numbers), cap(numbers), numbers)

可以看到二倍扩容了。
在这里插入图片描述

关于截取很简单,用下标和冒号截取,区间是左闭右开。

//左闭右开
t := numbers[3:6]
fmt.Printf("len: %d, cap: %d, slice: %v\n", len(t), cap(t), t)

要注意的是:t和numbers是同一个切片。t只是numbers的引用而已。它们两个底层的数组是一样的。

逻辑如下:
Go 数组 slice map type struct_第2张图片
用len和开始的索引来表示截取后的切片,至于cap,是不会变的。
在这里插入图片描述

如果想拷贝slice里面的元素到新的slice(memcpy),要使用copy函数。

Go 数组 slice map type struct_第3张图片

var t = []int{1, 2, 3}
fmt.Printf("len: %d, cap: %d, slice: %v, addr: %p\n", len(t), cap(t), t, &t)

s := make([]int, 3)
copy(s, t)//把t的值拷贝给s
fmt.Printf("len: %d, cap: %d, slice: %v, addr: %p\n", len(s), cap(s), s, &s)

map四种声明方式

第一种声明,这个map是空的
var mymap1 map[string]string
if mymap1 == nil {
	fmt.Println("mymap1 is empty")
}

第二种声明,声明+make开辟空间
var mymap2 = make(map[string]string, 10)
mymap2["c++"] = "1"
mymap2["java"] = "2"

第三种:= + make
mymap3 := make(map[string]string) //make会自己给你一点空间的,一开始给不给无所谓了
mymap3["c++"] = "1"
mymap3["java"] = "2"

第四种:= + 大括号初始化定义
mymap4 := map[string]string{"c++": "one", "java": "two"}
fmt.Println(mymap4)`

其实就最后两种有用一点。
一定要记住:凡是容器都要make才会开空间的.

map的一些操作

遍历

遍历map可以用range来遍历

for key, value := range mymap4 {
		fmt.Println(key, " ", value)
	}

删除

删除关键字,用delete。delete和make都是go的关键字
Go 数组 slice map type struct_第4张图片

delete(mymap4, "c++")

函数传参(引用)

函数内部可以修改

func PrintMap(mymap map[string]string) {
	for key, value := range mymap {
		fmt.Println(key, " ", value)
	}
	修改操作有效
	mymap["c++"] = "666"
}

题外话:

要初始化变量只有这两种方法
写了:=就不能写类型和var
写了var和类型就不能写:=
写了类型必须带上var,写了var必须带上类型

b := 1
a := 2
var b int = 1
var a int = 1

type

type并不是像c++一样取别名。c++里面别名之间只要类型相同,它们就可以赋值,但是go不行。

这段代码是行不通的

type myint int
var b myint = 1
var a int = 2
a, b = b, a 交换a和b两个值

在这里插入图片描述

struct

结构体的声明和C++差不多,但是有一点不同并且挺重要的。

go没有->这个符号,即使你是对象的地址,也是用.来访问成员

type Country struct {
	capital string
	name    string
}

struct的初始化和map的最后一种初始化差不多,可以用大括号来初始化。

key: value的形式来初始化

h := human{name: "zhangsan", gender: "male"}

结构体对象函数传参

和C++一样,要改变就传指针。

func printCountry1(foo Country) {
	fmt.Print(foo)
	fmt.Println()
}

func printCountry2(foo *Country) {
	fmt.Print((foo))
}


var foo Country
foo.capital = "beijing"
foo.name = "china"

//fmt.Printf("%v", foo)
printCountry1(foo)
printCountry2(&foo)

在这里插入图片描述
go的print是万能的,它什么都能打印出来!!!

你可能感兴趣的:(Go语法,golang,开发语言,后端)