package main
import"fmt"// struct 定义结构体, 类似python中的类, 值类型type student struct{// 首字母大写才外部可见
name string
age int
score int}// 构造函数, 这里实际上和结构体没有关系, 只是通过函数实例化一个结构体 funcnewStudent(name string, age, score int)*student {return&student{
name: name,
age: age,
score: score,// 逗号必不可少}}// 结构体的方法, 需要用 (s *stu) 声明了接收的结构体, s为约定俗称的写法func(s *stu)printScore(){
fmt.Println(s.score)}funcmain(){// 实例化
stu1 :=newStu("Tim",18,100)// 取值
fmt.Println(stu1.name, stu1.age, stu1.score)// 调用结构体方法
stu1.printScore()}
实例化的几种写法
package main
import"fmt"type stu struct{
name string
age int
score intfuncmain(){// 方法 1
p1 := stu{}// 没有赋值, 结构体内所有的值都为零值
fmt.Println(p1)// 方法 2
p2 :=new(stu)// 方法 3
p3 :=&stu{}
fmt.Println(p2, p3)// 得到的都是指针// 值类型: 初始化 = 实例化+赋值
stu2 := stu{
name:"a",
score:100,// 由于声明了 key, 所以可以不按顺序
age:18,}
fmt.Println(stu2)
stu3 := stu{"a",19,120,}
fmt.Println(stu3)}
指针接收者和值接收者
当需要修改结构体内部属性的时候, 方法使用指针接收者
只需要取值的之后, 方法可以使用值接收者
package main
import"fmt"type stu struct{
name string
score int}// 值接收者, 适用于单纯取值func(s stu)getScore(){
fmt.Println(s.score)}// 指针接收者, 适用于需要修改结构体的内部属性时使用func(s *stu)setScore(newScore int){
s.score = newScore
}funcmain(){
stu1 := stu{name:"Tim", score:100}// 得到成绩
stu1.getScore()// 更改成绩
stu1.setScore(99)
fmt.Println(stu1.score)}
结构体的其他用法
嵌套结构体
package main
import"fmt"type address struct{
country string
city string}type person struct{
name string
age int
addr address
}funcmain(){
p1 := person{
name:"Tim",
age:22,
addr: address{
country:"中国",
city:"北京",},}
fmt.Println(p1.addr.city)// 必须一层一层找}
嵌套匿名结构体
package main
import"fmt"type address struct{
country string
city string}type person struct{
name string
age int
address
}funcmain(){
p1 := person{
name:"Tim",
age:22,
address: address{
country:"中国",
city:"北京",},}// 可以使用完整的, 也可以使用简写
fmt.Println(p1.address.city)
fmt.Println(p1.city)// city 在上一层必须没有}
package main
// 并不推荐的一种写法import"fmt"type cat struct{
name stringint// 未声明属性名, 只声明了类型, 这种没有属性名的类型不可重复出现bool}funcmain(){
c1 := cat{name:"Tim",int:3,bool:true}
fmt.Println(c1)}
证明: 结构体中属性的内存布局
package main
import"fmt"// 结构体占用连续内存空间funcmain(){type test struct{
a int16
b int16
c int16}var t = test{
a:1,
b:2,
c:3,}
fmt.Println(&(t.a))// 0xc000096000
fmt.Println(&(t.b))// 0xc000096001
fmt.Println(&(t.c))// 0xc000096002}