结构体的介绍:
- golang支持面向对象,是基于struct来实现OOP特性的,相当于Java中的class类。
- golang去掉了传统的oop语言的继承,方法重载,构造函数和析构函数,隐藏的this指针。
- golang仍然有面向对象编程的继承,封装和多态的特性。但是golang的继承没有extends关键字,继承是通过匿名字段来实现的。
代码举例:
package model
// Cat 定义一个结构体
type Cat struct {
Name string
Age int
Color string
Hobby string
}
package main
import (
"fmt"
"mygo_code/chapter8/demo08/model"
)
func main() {
//创建一个cat的变量
var cat model.Cat
cat.Name = "小白"
cat.Age = 1
cat.Color = "白色"
cat.Hobby = "玩耍"
fmt.Println("cat=", cat)//cat= {小白 1 白色 玩耍}
}
结构体变量在内存的布局
如何声明结构体
type 结构体名称 struct{ type Student struct{
field1 type Name string
field2 type -> Age int
} }
字段/属性:
基本介绍:字段是结构体的一个组成部分,一般是基本数据类型,数组,也可是引用类型。比如我们前面定义猫结构的Name string就是属性。
细节:
- 字段声明语法同变量,示例:字段名 字段类型。Name string
- 字段的类型可以为:基本类型,数组或引用类型。
- 在创建一个结构体变量后,如果没有给字段赋值,都对应一个零值(默认值)。指针,slice,和map的零值都是nil,即还没有分配空间。
- 不同的结构体变量的字段是独立的,互不影响,一个结构体变量的字段的更改,不影响另外一个,结构体是值类型。
var m1 model.Monster
m1.Name = "小怪兽"
m1.Age = 500
m2 := m1 //这里其实把m1的值拷贝了一份给m2
m2.Name = "大怪兽"
fmt.Println("m1=", m1) //m1的Name没有被修改 因为结构体是值类型
fmt.Println("m2=", m2)
创建结构体的方式
func main() {
//创建结构体的方法1
var person model.Person //定义一个Person结构体
person.Name = "张三" //给结构体赋值
person.Age = 18 //给结构体赋值
fmt.Println("person=", person)
//创建结构体的方法2
person2 := model.Person{
Name: "李四",
Age: 19,
}
fmt.Println("person2=", person2)
//创建结构体的方法3
var person3 *model.Person = new(model.Person) //使用new函数创建结构体 返回的是结构体的指针
(*person3).Name = "王五" //因为person3是指针,所以需要使用*person3来访问结构体的属性
person3.Age = 20 //也可以这样使用 go的设计者为了简化代码,提供了这种简写形式
fmt.Println("person3=", *person3) //person3是指针,所以需要使用*person3来访问结构体的属性
//创建结构体的方法4
person4 := &model.Person{
Name: "赵六",
Age: 21,
} //使用&符号创建结构体,返回的是结构体的指针
fmt.Println("person4=", *person4) //person4是指针,所以需要使用*person4来访问结构体的属性
}
- 第三种和第四种方式返回的是结构体的指针。
- 结构体指针访问字段的标准格式是:(结构体指针名).属性名,比如 (person3).Name = "王五"。
- go的设计者为了简化代码,提供了这种简写形式,比如 person3.Name = "王五"也可以。go的编译器对person3.Name做了转化为(*person3).Name。