go 基础-3
指针
可以理解为就是内存地址
-
函数是值拷贝操作,所以要修改值就需要用到指针操作
-
对变量进行取地址(&)操作,可以获得这个变量的指针变量。
-
指针变量的值是指针地址。
-
对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。
func modify1(x int) {
x = 100
}
func modify2(x *int) {
*x = 100
}
func main() {
a := 10
modify1(a)
fmt.Println(a) // 10
modify2(&a)
fmt.Println(a) // 100
}
-
new和make用来做内存分配的,因为Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储,就会出发panic,所以要用new和make来做内存分配。
-
二者都是用来做内存分配的。
-
make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
-
而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。
-
new返回的是一个指向该类型内存地址的指针,比如int就返回*int
-
make返回类型本身
func main() {
var a *int
a = new(int)
*a = 100
fmt.Println(*a)
var b map[string]int
b = make(map[string]int, 10)
b["xxx"] = 100
fmt.Println(b)
}
结构体
结构体有点类似python中的类
package main
import (
"fmt"
"os"
)
func main() {
sm := NewStudentMan()
for {
ShowMenu()
var input int
fmt.Println("choose number")
fmt.Scanf("%d /n", &input)
switch input {
case 1:
stu := getInput()
sm.addStudent(stu)
case 2:
stu := getInput()
sm.modifyStudent(stu)
case 3:
sm.showStudentList()
case 4:
os.Exit(0)
}
}
}
// 获取用户的输入信息
func getInput() *Student{
var (
id int
name string
age int
score int
)
fmt.Println("please input student message")
fmt.Println("please enter id")
fmt.Scanf("%d \n", &id)
fmt.Println("please enter name")
fmt.Scanf("%s \n", &name)
fmt.Println("please enter age")
fmt.Scanf("%d \n", &age)
fmt.Println("please enter score")
fmt.Scanf("%d \n", &score)
stu := NewStudent(id, age, score, name)
return stu
}
// ShowMenu 展示菜单
func ShowMenu() {
fmt.Println("WelCome")
fmt.Println("Press 1 add student")
fmt.Println("Press 2 modify student")
fmt.Println("Press 3 show all student")
fmt.Println("Press 4 exit")
}
// Student 定义学生的结构体,结构体类似python中的类
type Student struct {
id int
name string
age int
score int
}
// NewStudent 定义Student的构造函数,构造函数就是类似python类中的__init__函数,用指针是因为struct是值类型,所以值拷贝的开销会比较大
func NewStudent(id,age,score int, name string) *Student{
return &Student{
id: id,
name: name,
age: age,
score: score,
}
}
// StudentMan 定义StudentMan的结构体,allStudents是一个 Student的指针切片
type StudentMan struct {
allStudents []*Student
}
// NewStudentMan StudentMan的构造函数,allStudents是一个切片,所以需要用make来初始化分配内存空间
func NewStudentMan() *StudentMan{
return &StudentMan{
allStudents: make([]*Student,0,50 ),
}
}
// 定义一个新增学生的方法,就是给StudentMan构造函数增加一个方法 go中的方法是一种叫做接收者的函数,类似python中的self,下面的s就是类似于self
func (s *StudentMan)addStudent(NewStu *Student) {
s.allStudents = append(s.allStudents, NewStu)
}
func (s *StudentMan)modifyStudent(NewStu *Student) {
for i, v :=range s.allStudents{
if NewStu.id == v.id{
s.allStudents[i] = NewStu
return
}
}
fmt.Println("未找到该学生")
}
func (s *StudentMan)showStudentList() {
for _, value := range s.allStudents{
fmt.Printf("学号: %d \n", value.id)
fmt.Printf("姓名: %s \n", value.name)
fmt.Printf("年龄: %d \n", value.age)
fmt.Printf("分数: %d \n", value.score)
}
}