Go 结构体

140 阅读4分钟

结构体实例变量

结构体中的方法

type Student struct {
   Name   string
   Age    int
   Skills []string
}

func (s *Student) Learn(skill string) {
   s.Skills = append(s.Skills, skill)
}

func (s *Student) SetName() {
   log.Println("修改名字前:" + s.Name)
   s.Name = "xiaoming"
   log.Println("修改名字后:" + s.Name)
}

func (s Student) SetNameTest() {
   log.Println("修改名字前:" + s.Name)
   s.Name = "xiaohong"
   log.Println("修改名字后:" + s.Name)
}

func main() {
   s := Student{}
   s.Name = "小刚"
   //log.Println(s.Name)
   s.SetName()
   s.SetNameTest()
   log.Println(s.Name)
}

打印结果

2022/04/25 14:16:06 修改名字前:小刚
2022/04/25 14:16:06 修改名字后:xiaoming
2022/04/25 14:16:06 修改名字前:xiaoming
2022/04/25 14:16:06 修改名字后:xiaohong
2022/04/25 14:16:06 xiaoming

可以看出

  • func (s Student) SetNameTest()中,接受者为实例变量的副本,在方法内更改值不会影响原来的值

  • func (s *Student) SetName()中,接受者为实例变量地址的副本,在方法内更改值会影响原来的值

package中的方法

同理在包中的方法也是一样

func SetName1(s *Student) {
   log.Println("修改名字前:" + s.Name)
   s.Name = "name1"
   log.Println("修改名字后:" + s.Name)
}

func SetName2(s Student) {
   log.Println("修改名字前:" + s.Name)
   s.Name = "name2"
   log.Println("修改名字后:" + s.Name)
}

func main() {
   var s Student
   s.Name = "小刚"
   //log.Println(s.Name)
   s.SetName()
   s.SetNameTest()

   log.Println("-------------分割线-------------")
   SetName1(&s)
   SetName2(s)
   log.Println(s.Name)
}

打印

2022/04/25 14:30:46 -------------分割线-------------
2022/04/25 14:30:46 修改名字前:xiaoming
2022/04/25 14:30:46 修改名字后:name1
2022/04/25 14:30:46 修改名字前:xiaoming
2022/04/25 14:30:46 修改名字后:name2
2022/04/25 14:30:46 xiaoming

结构体的定义

定义结构体的三种方式

var s1 Student // 在内存中直接定义一个结构体变量
s1 := new(Student) // 在内存中直接定义一个结构体变量
var s1 Student  // 在内存中直接定义一个结构体变量

构造函数

func NewStudent(name string, age int) *Student { // 返回值指向 Student 结构体的指针
   return &Student{
      Name: name,
      Age:  age,
   }
}
log.Println("-------------分割线-------------")
s1 := NewStudent("萌新", 123)
log.Println(s1.Name)
log.Println((*s1).Name)

打印

2022/04/25 14:50:28 -------------分割线-------------
2022/04/25 14:50:28 萌新
2022/04/25 14:50:28 萌新

匿名函数

type Class struct {
   ClassName string
}

func (cla *Class) OutClassName() {
   log.Println("班级名称:" + cla.ClassName)
}

type Student struct {
   Name   string
   Age    int
   Skills []string
   Class
}
log.Println("-------------分割线-------------")
s1 := NewStudent("萌新", 123)
log.Println(s1.Name)
log.Println((*s1).Name)
log.Println("-------------分割线-------------")

s1.ClassName = "1年级"
log.Println(s1.ClassName)
s1.OutClassName()

打印

2022/04/25 15:01:03 -------------分割线-------------
2022/04/25 15:01:03 萌新
2022/04/25 15:01:03 萌新
2022/04/25 15:01:03 -------------分割线-------------
2022/04/25 15:01:03 1年级
2022/04/25 15:01:03 班级名称:1年级

结构体继承结构体,其中被继承结构体的方法全部为继承结构体吸收

组合实现继承

继承

package main

import (
   "log"
   "strconv"
)

// struct 1
type Person struct {
   Name string
}

func (a *Person) Eat() {
   log.Println(a.Name + "想吃东西")
}

// struct 3
type Student struct {
   *Person
   Age    int
   Skills []string
}

func (s *Student) Eat() {
   log.Println(strconv.Itoa(s.Age) + "岁的" + s.Name + "想吃东西")
}

func NewStudent(name string, age int) *Student { // 返回值指向 Student 结构体的指针
   return &Student{Person: &Person{name}, Age: age}
}

// 结构体练习
func main() {
   log.Println("-------------分割线-------------")
   s1 := NewStudent("萌新", 123)
   log.Println(s1)
   log.Println(s1.Name)
   s1.Eat()
   log.Println("-------------分割线-------------")

}

打印

2022/04/25 15:38:19 -------------分割线-------------
2022/04/25 15:38:19 &{0xc000010250 123 []}
2022/04/25 15:38:19 萌新
2022/04/25 15:38:19 123岁的萌新想吃东西

参数多态

添加接口

type IPerson interface {
   Eat() // 描述吃的行为
}

func StartEat(animal IPerson) {
   animal.Eat()
}
// 结构体练习
func main() {
   log.Println("-------------分割线-------------")
   s1 := NewStudent("萌新", 123)
   log.Println(s1)
   log.Println(s1.Name)
   s1.Eat()

   log.Println("-------------分割线-------------")
   s := &Person{"老油条"}
   StartEat(s)
   StartEat(s1)
}
打印
2022/04/25 15:42:21 -------------分割线-------------
2022/04/25 15:42:21 老油条想吃东西
2022/04/25 15:42:21 123岁的萌新想吃东西

接口正在方法的话类也要增加

type IPerson interface {
   Eat() // 描述吃的行为
   Run()
}
// struct 1
type Person struct {
   Name string
}

func (a *Person) Run() {
   log.Println("跑步走起")
}
func (a *Person) Eat() {
   log.Println(a.Name + "想吃东西")
}

参考链接

Go结构体与方法

Go结构体方法

2分钟让你明白Go中如何继承