go学习之结构体

    go中的结构体类似python的类

结构体定义type 类型名 struct {
    字段名 字段类型
    字段名 字段类型
    …
}

例如:
type p struct {
	name string
	city string
	age  int8
}
 

 

结构体实列化

只有当结构体实例化时,才会真正地分配内存。也就是必须实例化后才能使用结构体的字段。
结构体本身也是一种类型,我们可以像声明内置类型一样使用var关键字声明结构体类型

格式如下:
var 结构体实例 结构体类型

例子:
var p1 p
p1.name = "张三"
p1.city = "北京"
p1.age = 18
创建指针类型结构体
可以使用 new 关键字对类型(包括结构体、整型、浮点数、字符串等)进行实例化,结构体在实例化后会形成指针类型的结构体 通过使用new关键字对结构体进行实例化,得到的是结构体的地址。 格式如下: var p2
= new(p) 需要注意的是在Go语言中支持对结构体指针直接使用.来访问结构体的成员 例如: var p1=new(p) fmt.Printf("%T\n", p1)//*main.p p1.name="小王" fmt.Printf("%s\n", p1.name)

 

取结构体的地址实例化

使用&对结构体进行取地址操作相当于对该结构体类型进行了一次new实例化操作。


p2 := &p{}
fmt.Printf("%T\n", p2)//*main.p
p2.name="小王"
fmt.Printf("%s\n", p2.name)//小王

p2.name = "小王"其实在底层是(*p2).name = "小王",这是Go语言帮我们实现的语法糖。
结构体初始化

1、定义未初始化时其成员变量都是对应其类型的零值
2、使用键值初始化
    例如:
        p1 := p{
    name: "lisi",
    city: "北京",
        }

3、使用值的列表初始化
    例如:
        p1 := p{
     "lisi",
     "北京",
        }

 

构造函数

Go语言的结构体没有构造函数,可以自己实现
struct是值类型,如果结构体比较复杂的话,值拷贝性能开销会比较大,所以该构造函数返回的是结构体指针类型
构造函数也是用来对结构体进行实列化 func newPerson(name, city
string) *person { return &person{ name: name, city: city, } } 调用 p1 := newPerson("张三", "上海")
Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)

方法定义格式如下:
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
    函数体
}

说明:
接收者变量:接收者中的参数变量名在命名时,官方建议使用接收者类型名称首字母的小写
接收者类型:接收者类型和参数类似,可以是指针类型和非指针类型
方法名、参数列表、返回参数:具体格式与函数定义相同


例子:
type Person struct {
    name string
    age  int8
}

func (p Person) Dream() {
    fmt.Printf("%s的梦想是学好Go语言!\n", p.name)
}
指针类型的接收者VS值类型的接收者

// 使用指针接收者
func (p *Person) SetAge(newAge int8) {
    p.age = newAge
}

func (p Person) SetAge2(newAge int8) {
    p.age = newAge
}


说明
当方法作用于值类型接收者时,Go语言会在代码运行时将接收者的值复制一份。在值类型接收者的方法中可以获取接收者的成员值,但修改操作只是针对副本,无法修改接收者变量本身
指针类型的接收者由一个结构体的指针组成,由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的

 

练习:函数版简单学生管理系统

package main

import "fmt"


var student_info map[int]string

func add_student(name string,id int){
    student_info[id]=name
    fmt.Println("add  student success")
}


func show_student(){
    for k,v := range student_info{
       fmt.Println(k, v)
    }

}


func del_student(){
    fmt.Println("请输入要删除的学生id:")
    var s_id int
    fmt.Scan(&s_id)
    delete(student_info,s_id)
    fmt.Println("现有学生如下:")
    show_student()
}

func ShowMessage() int {
    fmt.Println("要执行的操作:")
    fmt.Print(`
    1. 添加  
    2. 查看  
    3. 删除 
    `)
    var do int
    _, err := fmt.Scan(&do)
    if err != nil {
    fmt.Println("输入有误!")
    }

    return do
   
}



func main() {
    student_info=make(map[int]string,10)
    for {
        num :=ShowMessage()
        switch num {
        case 1 :
             fmt.Println("你选择的是:添加")
             var id int
             fmt.Println("请输入id:")
             fmt.Scan(&id)
             var name string
             fmt.Println("name:")
             fmt.Scan(&name)
             add_student(name,id)
        case 2 :
             fmt.Println("你选择的是:查看")
             fmt.Println("学生信息如下:")
             show_student()
        case 3 :
             fmt.Println("你选择的是:删除")
             del_student()
        default :
             fmt.Println("你选择有误请重新选择")

        }
        

    }

}
code
执行效果
go run student.go 
要执行的操作:

    1. 添加  
    2. 查看  
    3. 删除 
    1
你选择的是:添加
请输入id:
1
name:
zhangsan
add  student success
要执行的操作:

    1. 添加  
    2. 查看  
    3. 删除 
    2
你选择的是:查看
学生信息如下:
1 zhangsan
要执行的操作:

    1. 添加  
    2. 查看  
    3. 删除 
    3
你选择的是:删除
请输入要删除的学生id:
1
现有学生如下:
要执行的操作:

    1. 添加  
    2. 查看  
    3. 删除 
    

 

结构体“继承”

 

 

结构体与JSON序列化和反序列化

//JSON序列化:结构体-->JSON格式的字符串
data, err := json.Marshal(s)
if err != nil {
    fmt.Println("json marshal failed")
    return
}


//JSON反序列化:JSON格式的字符串-->结构体

err = json.Unmarshal([]byte(str), c1)
if err != nil {
    fmt.Println("json unmarshal failed!")
    return
}
结构体Tag

type Student struct {
    ID     int    `json:"id"` //通过指定tag实现json序列化该字段时的key
    Gender string //json序列化是默认使用字段名作为key
    name   string //私有不能被json包访问
}

 

练习:结构体版学生管理

package main

import (
    "fmt"
    "os"
)

func showMenu(){
    fmt.Println("welcomm sms!")
    fmt.Println(`
    1. 查看学生
    2. 添加学生
    3. 修改学生
    4. 删除学生
    5. 退出
    `)

}

//定义一个学生结构体,用来保存单个学生信息
type student struct{
    id int
    name string
}

//定义一个学生管理的结构体,包含各种学生管理相关的方法
type studentMgr struct {
    allStudent map[int]student //定义一个allStudent map,其中键是int,值是student的结构体(即上面定义的)
}

//查看学生信息
func (s studentMgr) showStudent() {
    fmt.Println("学生信息如下:")
    for _,v :=range s.allStudent {
       fmt.Println(v.id, v.name)
    }

}

//添加学生
func (s studentMgr) addStudent() {
    var stuId int
    var stuName string
    fmt.Print("请输入学号:")
    fmt.Scanln(&stuId)//获取指针以便修改值
    fmt.Print("请输入姓名:")
    fmt.Scanln(&stuName)
    newstu := student{
        id: stuId,
        name: stuName,
    }

    s.allStudent[newstu.id] = newstu 
}



//修改
func (s studentMgr) editStudent() {


fmt.Println("请输入学生的学号")
    var stuId int
    fmt.Scanln(&stuId)

    v1, ok := s.allStudent[stuId] // 直接使用 map 的key 就能取值
    if !ok {
        fmt.Println("查无此人")
        return
    }
    fmt.Println("将修改学生的名字", v1.name)
    fmt.Print("请输入学生的新名字")
    var newName string
    fmt.Scanln(&newName)
    v1.name = newName            // 直接进行更改
    s.allStudent[stuId] = v1 // 再更改到map 里
    fmt.Print("学生信息修改成功")

}

//删除学生
func (s studentMgr) deleteStudent() {

    fmt.Println("请输入你要删除学生的学号")
    var studID int
    fmt.Scanln(&studID) // 要删除学生的ID
    delete(s.allStudent, studID) 
    fmt.Println("删除成功")

}

//
var smr studentMgr

func main(){
    smr = studentMgr{
        allStudent: make(map[int]student),
    }
 
    for {
        showMenu()
        fmt.Println("请输入你的操作")
        var choice int
        fmt.Scanln(&choice)
        switch choice {
        case 1:
            smr.showStudent()
        case 2:
            smr.addStudent()
        case 3:
            smr.editStudent()
        case 4:
            smr.deleteStudent()
        case 5:
            os.Exit(1)
        default:
            fmt.Println("选择错误,请重新选择")
        }


    }

}
结构体版本学生管理系统

 

执行结果
welcomm sms!
    1. 查看学生
    2. 添加学生
    3. 修改学生
    4. 删除学生
    5. 退出 
请输入你的操作
2
请输入学号:001
请输入姓名:root
welcomm sms!
    1. 查看学生
    2. 添加学生
    3. 修改学生
    4. 删除学生
    5. 退出
请输入你的操作
1
学生信息如下:
1 root
welcomm sms!
    1. 查看学生
    2. 添加学生
    3. 修改学生
    4. 删除学生
    5. 退出
请输入你的操作
2
请输入学号:002
请输入姓名:admin
welcomm sms!
    1. 查看学生
    2. 添加学生
    3. 修改学生
    4. 删除学生
    5. 退出
请输入你的操作
3
请输入学生的学号
001
将修改学生的名字 root
请输入学生的新名字root1
学生信息修改成功welcomm sms!
    1. 查看学生
    2. 添加学生
    3. 修改学生
    4. 删除学生
    5. 退出 
请输入你的操作
4
请输入你要删除学生的学号
001
删除成功
执行结果

 

posted @ 2021-08-23 19:57  泉love水  阅读(61)  评论(0编辑  收藏  举报