跳到主要内容

数据类型

1.基本数据类型

1.4 布尔型

2.复合数据类型

2.1 数组 array

2.1.1 说明

说明
  • 数组是指一系列同一类型数据的集合
  • 数组中包含的每个数据被称为数组元素(element),这种类型可以是任意的原始类型,例如 intstring
  • 一个数组包含的元素个数被称为数组的长度
  • 数组是一个长度固定的数据类型,数组的长度是类型的一部分,[5]int[10]int 是不同的类型

2.1.2 定义方式

说明
  • 数组的长度必须是常量,并且长度是数组的类型的一部分
  • 数组一旦定义,长度不可变,元素可变
var 数组名称 [元素数量]类型
  • 方式1 指定长度和类型

    var arr [5]int // 长度为5的int数组,初始值为[0, 0, 0, 0, 0]
  • 方式2 指定长度和类型同时初始化

    arr := [5]int{1, 2, 3, 4, 5} // 长度为5,初始值为[1, 2, 3, 4, 5]
  • 方式3 使用 ... 让编译器自动推断长度

    arr := [...]int{1, 2, 3} // 自动推断长度为3

代码示例

package main

import "fmt"

func main() {

// 定义一个长度为5,类型为int的空数组
var a [5]int

// 定义一个长度为3,类型为int的数组并赋值
var b [3]int
b[0] = 80
b[1] = 90
b[2] = 100

// 定义一个长度为3,类型为int的数组并赋值
c := [3]int{1, 2, 3}

fmt.Println("a:", a)
fmt.Println("b:", b)
fmt.Println("c:", c)
}

输出

a: [0 0 0 0 0]
b: [80 90 100]
c: [1 2 3]

2.1.3 使用示例

普通遍历数组

package main

import "fmt"

func main() {

var a = [5]string{"北京", "上海", "广州", "深圳", "杭州"}
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
}

输出

北京
上海
广州
深圳
杭州

k,v 遍历数组

package main

import "fmt"

func main() {
var a = [5]string{"北京", "上海", "广州", "深圳", "杭州"}
for index, value := range a {
fmt.Println(index, value)
}
}

输出

0 北京
1 上海
2 广州
3 深圳
4 杭州

数组与切片的区别

特性数组切片
长度是否固定固定可变
定义时是否需要长度必须指定长度(或用 ... 推断)不需要,直接用 [] 定义
是否值类型是(传递时会拷贝整个数组)否(传递的是引用)
初始化方式[n]type{...}[]type{...}
使用 make 创建不支持支持
底层结构直接存储元素基于数组,提供灵活操作

2.2 切片 slice

2.2.1 说明

说明

切片是一个拥有 相同类型元素可变长度 的序列

2.2.2 定义方式

说明

T 代表切片元素类型,可以是整型、浮点型、布尔型、切片、map、函数等

切片的元素使用 [] 进行访问,在方括号中提供切片的索引即可访问元素,索引的范围从0开始,且不超过切片的最大容量

var name []T
  • 方式1 使用 make 创建

    slice := make([]int, 5) // 创建长度为5的切片,初始值为[0, 0, 0, 0, 0]
  • 方式2 直接初始化

    slice := []int{1, 2, 3} // 创建切片并初始化
  • 方式3 从现有数组中创建切片

    arr := [5]int{1, 2, 3, 4, 5}
    slice := arr[1:4] // 从数组的第2到第4个元素生成切片

2.2.3 使用示例

2.3 字典 map

2.4 结构体 struct

2.5 接口 interface

2.6 通道 channel

2.7 指针 pointer

2.7.1 说明

说明

指针概念在go语言中被拆分为2个核心概念

  • 类型指针,允许对这个指针类型的数据进行修改,传递数据使用指针,而无须拷贝数据,类型指针不能进行偏移和运算
  • 切片,由指向起始元素的原始指针、元素数量和容量组成

2.7.2 定义方式

2.7.2.1 指针类型声明
说明

指针类型用 * 表示,指向某种类型的变量

var ptr *int // 指向一个 int 类型的指针

通过 new() 函数创建

new(类型)
package main

import "fmt"

func main() {
str := new(string)
*str = "我尼玛"
fmt.Println(*str)
}

输出

我尼玛
2.7.2.2 获取指针地址
说明

使用 & 操作符获取变量的地址

var a int = 10
var ptr *int = &a // 将 a 的地址赋值给 ptr
2.7.2.3 通过指针访问值
说明

使用 * 操作符(解引用)访问指针指向的变量

fmt.Println(*ptr) // 输出 a 的值,即 10

2.7.3 使用示例

2.7.3.1 指针地址和指针类型
说明

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置,go语言中使用 & 操作符放在变量前边对变量进行 取地址 操作,格式如下

ptr := &v // v的类型为T

其中 v 代表被取地址的变量,被取地址的 v 使用 ptr 变量进行接收,ptr 的类型就为 *T ,称作 T 的指针类型,* 代表指针

获取变量取地址后的指针值

package main

import "fmt"

func main() {
var cat int = 1
var str string = "hahaha"

fmt.Printf("%p %p", &cat, &str)
}

输出

说明
  • 输出值在每次运行是不同的,代表 catstr 变量取地址后的指针值,指针值带有 0x 的十六进制前缀

  • 变量、指针和地址三者的关系是:每个变量都拥有地址,指针的值就是地址

0x14000098020 0x1400008e170
2.7.3.2 从指针获取指针指向的值
说明

在对普通变量使用 & 操作符取地址获得这个变量的指针后,可以对指针使用 * 操作,也就是指针取值

package main

import "fmt"

func main() {
// 准备一个字符串类型
var house = "北京市朝阳区将台路666号"

// 对字符串取地址,ptr类型为 *string
ptr := &house

// 打印ptr的类型
fmt.Printf("ptr type: %T\n", ptr)

// 打印ptr的指针地址
fmt.Printf("ptr address: %p\n", ptr)

// 对指针进行取值操作
value := *ptr

// 取值后的类型
fmt.Printf("value type: %T\n", value)

// 指针取值后就是指向变量的值
fmt.Printf("value: %s\n", value)
}

输出

说明

取地址操作符 & 和取值操作符 * 是一对互补操作符,& 取出地址,* 根据地址取出地址指向的值

变量,指针地址、指针变量、取地址、取值的相互关系和特性如下

  • 对变量进行取地址(&)操作,可以获得这个变量的指针变量
  • 指针变量的值就是指针地址
  • 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值
ptr type: *string
ptr address: 0x1400008e170
value type: string
value: 北京市朝阳区将台666号
2.7.3.3 使用指针修改值
注意
  • * 操作符作为右值时,意思是取指针的值;作为左值时,也就是放在赋值操作符的左边时,表示a指向的变量
  • * 操作符的根本意义就是操作指针指向的变量
    • 当操作在右值时,就是取指向变量的值
    • 当操作在左值时,就是将值设置给指向的变量
package main

import "fmt"

// 交换函数
func swap(a, b *int) {
// 取a指针的值,赋给临时变量t
t := *a

// 取b指针的值,赋给a指针指向的变量
*a = *b // 这里的 *a 是a指向的变量,不是取a指针的值

// 将a指针的值赋给b指针指向的变量
*b = t
}

func main() {
// 准备2个变量,赋值1和2
x, y := 1, 2

// 交换变量值
swap(&x, &y)

// 输出变量值
fmt.Println(x, y)
}

输出

2 1
Right Bottom Gif
Right Top GIF