0
点赞
收藏
分享

微信扫一扫

GO 学习笔记——第三天 / 复合类型

指针:pointer 数组:array 切片:slice 字典:map 结构体:struct

1.指针

  • 基本概念
package main

import "fmt"

func main() {

var a int = 10

fmt.Println("内存:", a, "地址:", &a)
//输出 内存: 10 地址: 0xc00004e080

//保存某个变量的地址 需要指针类型 *int保存int的地址 **int保存*int的资质
var p *int
p = &a

fmt.Println("p:", p)
//输出

//操作的是p所指向的内存地址 也就是a
*p = 20

fmt.Println("a:", a, "p:", p)
//输出 a: 20 p: 0xc00004e080

//不能操作没有指向的指针
var b *int
*b = 30
//错误代码
}
  • new关键字
package main

import "fmt"

func main() {

var p *int
//p = &a
//申请空间
p = new(int)

*p = 20

fmt.Println("*p:", p)
//输出 *p:0xc000012158
}
  • 值传递的意思是我只是把值给你了,但是内存地址以及对应的值不变
  • 指针传递才可操作变量

2.数组

  • 声明:var a [20]int
  • 自动推导类型
package main

import "fmt"

func main() {

//var id [3]int = [3]int{1, 2, 3}
id := [3]int{1, 2, 3}
fmt.Println(id)
//输出[1 2 3]

//指定下标初始化
a := [5]int{2: 10, 4: 20}
fmt.Println(a)
//输出 [0 0 10 0 20]
}
  • 多维数组: a:= [3][4]{{},{},{},{}}
  • 数组允许比较和赋值 == !=
  • 随机数
package main

import "fmt"
import "math/rand"
import "time"

func main() {

//随机数 以时间作为种子参数
rand.Seed(time.Now().UnixNano())

for i := 0; i < 10; i++ {
//限定范围 0 - 100
fmt.Println("rand:", rand.Intn(100))
}
}
  • 冒泡排序
  • 挨着的两个数比较并且交换
package main

import "fmt"
import "math/rand"
import "time"

func main() {

rand.Seed(time.Now().UnixNano())

//随机数组
var a [10]int
n := len(a)

for i := 0; i < n; i++ {
a[i] = rand.Intn(100)
}

fmt.Println(a)

//冒泡排序
for i := 0; i < n-1; i++ {
for j := 0; j < n-1-i; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j]
}
}
}
fmt.Println(a)
}
  • 数组做参数传递
package main

import "fmt"

func main() {

a := [5]int{1, 2, 3, 4, 5}
Test(a)
Test01(&a)
}

//值传递
func Test(a [5]int) {
fmt.Println(a)
}

//引用传递
func Test01(p *[5]int) {
fmt.Println(*p)
}

3.slice

  • 切片的概念:切片并不是数组或者数组指针,他通过内部指针和相关属性引用数组片段,以实现变长方案
  • 切片的本质并不是一个动态数组,而是一个引用类型,slice总是指向一个底层array,slice的声明也可以像array一样,只是不需要长度。
    GO 学习笔记——第三天 / 复合类型_引用传递
  • 切片内部的意义:[low:height:max]
  • 长度:height - low
  • 容量:max - low
  • 数组和切片的区别
package main

import "fmt"

func main() {

//切片和数组的区别
//数组[]里面的长度是一个固定的常量,len和cap永远都是这个固定的常量
a := [5]int{}
fmt.Println("len:", len(a), "cap:", cap(a))
//len: 5 cap: 5
//切片[]里面为空,长度不固定
s := []int{}
fmt.Println("len:", len(s), "cap:", cap(s))
//len: 0 cap: 0
//追加
s = append(s, 10)
fmt.Println("append len:", len(s), "cap:", cap(s))
//append len: 1 cap: 1
}
  • 切片的创建方式
package main

import "fmt"

func main() {

//切片的创建方式
//1.自动推导类型
s1 := []int{1, 2, 3}
//2.借助make[切片类型,长度,容量]
s2 := make([]int,5,10)
//长度和容量都为5
s3 := make([]int,5)
}
  • 切片截取
    GO 学习笔记——第三天 / 复合类型_数组_02
  • append函数:在切片末尾处增加数据
  • copy(源,操作):将操作切片覆盖到源切片
  • 切片函数传参为引用传递

4.map

  • map是无序的
  • map做函数参数为引用传递
package main

import "fmt"

func main() {

m1 := make(map[int]string)
m2 := make(map[string]string)
m3 := map[int]int{1: 1, 2: 2, 3: 3}

m1[1] = "H"
m1[2] = "e"
m1[3] = "l"
m1[4] = "l"
m1[5] = "o"

m2["i"] = "o"

fmt.Println("-------------")
fmt.Println(m1)
//map[1:H 2:e 3:l 4:l 5:o]
fmt.Println("-------------")
fmt.Println(m2)
//map[i:o]
fmt.Println("-------------")
fmt.Println(m3)
//map[1:1 2:2 3:3]

//修改
m2["i"] = "j"
fmt.Println(m2)
//map[i:j]

//遍历
for key, values := range m1 {
fmt.Println("key:", key, "values:", values)
/*
key: 5 values: o
key: 1 values: H
key: 2 values: e
key: 3 values: l
key: 4 values: l
*/
}

//判断key是否存在
values, isHave := m1[5]

fmt.Println("values", values, "isHave:", isHave)
//values o isHave: true

//删除
delete(m1, 3)
fmt.Println(m1)
//map[4:l 5:o 1:H 2:e]
}

5.结构体

package main

import "fmt"

//结构体学生
type Student struct {
id int
name string
sex bool
age int
addr string
}

func main() {

//顺序初始化,每个成员都必须初始化
var s Student = Student{1, "LGL", true, 20, "jx"}
s.age = 30
fmt.Println(s)
//{1 LGL true 20 jx}

//指定成员初始化
s1 := Student{id: 1, addr: "bj"}
fmt.Println(s1)
//{1 false 0 bj}

//指针
var s2 *Student = &Student{1, "LGL", true, 20, "jx"}
s3 := &Student{id: 1, addr: "bj"}
fmt.Println(*s2)
fmt.Println(*s3)

//new
s4 := new(Student)·
s4.id = 1

//结构体的比较
//直接 = !=

//参数传递
//和变量传递一样,值传递和引用传递
}

6.可见性

  • 要让某个符号被其他package访问,需要定义大写开头
  • 在结构体中也是一样的,如果其他package调用结构体中的参数则需要大写开头

举报

相关推荐

0 条评论