struct 称为结构体,它可以用来描述现实中的一些事物对象
它定义了一些不同类型的变量,用这些不同的变量类型来描述事物对象的属性
格式
type 结构体名 struct {}
定义并初始化结构体
方法一
package main
import "fmt"
type Student struct {
Name string
Id string
Age string
}
func main() {
var student Student
student.Name = "陈九礼"
student.Age = "9999"
student.Id = "1314520"
fmt.Println(student)
}
输出
{陈九礼 1314520 9999}
方法二
package main
import "fmt"
type Student struct {
Name string
Id string
Age string
}
func main() {
student := Student{
Name: "陈九礼",
}
fmt.Println(student)
}
输出
{陈九礼 }
方法二在这里要注意几点
- 如果只想定义结构体,不想初始化结构体,那么结构体后面的 { }也别忘记添加
- 如果你要初始化一些变量,那么在变量值后,都要给它加上一个逗号 ,
- 可以不全部初始化完毕,也可以全部初始化完
结构体函数
在某些语言中,里面没有结构体,也没有函数。例如Java,有的只是类还有类中的方法。
在go中,也是有着跟结构体搭配在一起的函数,虽然长的样子跟函数有点差不多
但跟普通函数不一样的是,结构体函数的调用只能通过函数去调用
结构体函数的格式
func (变量名 结构体类型) 方法名([参数]) [返回类型]{ [函数体] }
[ ]表示可选的意思
结构体类型有两种:
1.指针类型的
2.普通类型的
后面会展示两种类型的样子
结构体函数的使用
指针类型的结构体函数
package main
import "fmt"
type Student struct {
Name string
Id string
Age string
}
func (student *Student) setName(name string) {
student.Name = name
}
func main() {
student := Student{}
student.setName("陈九礼")
fmt.Println("学生姓名:", student.Name)
}
输出
学生姓名: 陈九礼
普通类型的结构体函数
package main
import "fmt"
type Student struct {
Name string
Id string
Age string
}
func (student *Student) setName(name string) {
student.Name = name
}
func (student Student) setAge(age string) {
student.Age = age
}
func main() {
student := Student{}
student.setName("陈九礼")
student.setAge("9999")
fmt.Println("学生姓名:", student.Name)
fmt.Println("学生年龄:", student.Age)
}
输出
学生姓名: 陈九礼
学生年龄:
从输出可以看出,如果用的是普通类型的结构体,那么修改的值,并不会作用到原对象
普通类型结构体函数和指针类型结构体函数的区别
以下仅个人说法:
其实在结构体的函数中,我更愿意称结构体函数为:跟结构体绑定的函数
无论用的是普通绑定还是指针类型去绑定,都是说这个函数属于这个结构体的
普通类型结构体函数,你可以这么认为,就是我们调用这个函数的时候,结构体传入的是原本结构体的副本(也就是复制了一份过去),所以你修改了这个副本,并不会影响到原来的结构体
指针类型结构体函数,每次调用这个函数的时候,结构体传入的是这个结构体的指针(这里不纠结是值传递还是指针传递),函数可以根据这个结构体的指针,对原结构体里面的内容加以操作,这些操作,会作用于原结构体中
调用的时候,看做结构体是从这里传递进去的
结构体变量的作用范围
在学结构体之前,我们都学过了,变量的作用范围
变量的作用范围是被变量名大小控制的
main.go
package main
import "fmt"
type Student struct {
Name string
Id string
age string
}
func main() {
student := Student{
age: "9999",
Name: "陈九礼",
}
fmt.Println(student)
fmt.Println("同个包,但是不同文件中的函数:")
testScope()
}
test.go
package main
import "fmt"
func testScope() {
student := Student{
age: "8888",
Name: "陈陈陈",
}
fmt.Println(student)
}
输出
{陈九礼 9999}
同个包,但是不同文件中的函数:
{陈陈陈 8888}
从输出可以看出,在同一个包下,变量名的大小写的作用范围一样
结构体内的结构体变量
显示指定结构体变量名
package main
import "fmt"
type Person struct {
Name string
age string
}
type Student struct {
person Person
Id string
}
func main() {
student := Student{
person: Person{
Name: "陈九礼",
age: "9999",
},
Id: "1314520",
}
fmt.Println("通过显示调用Name: ", student.person.Name)
fmt.Println("通过显示调用age: ", student.person.age)
fmt.Println("调用Id", student.Id)
}
输出
通过显示调用Name: 陈九礼
通过显示调用age: 9999
调用Id 1314520
隐示指定结构体变量名
package main
import "fmt"
type Person struct {
Name string
age string
}
type Student struct {
Person
Id string
}
func main() {
student := Student{
Person: Person{
Name: "陈九礼",
age: "9999",
},
Id: "1314520",
}
fmt.Println("通过person调用Name: ", student.Person.Name)
fmt.Println("直接调用age: ", student.age)
fmt.Println("调用Id: ", student.Id)
}
输出
通过person调用Name: 陈九礼
直接调用age: 9999
调用Id: 1314520
通过隐示指定结构体变量名的方式,我们有两种调用属性的方式
第一种是直接调用嵌套函数的变量(如果外层结构体变量没有跟内层结构体变量重名的话)
第二种是间接调用,外层结构体调用内存结构体再调用到里面的变量
欢迎大家关注下个人的「公众号」:独醉贪欢