【Go】结构体的基本使用
go语言不是面向对象的语言
但是结构体类似于面向对象
结构体的定义
package main
import "fmt"
type Student struct {
id int
name string
age int
school string
}
func main() {
s := Student{1, "luobozi", 18, "znl"}
fmt.Println(s)
}
结构体实例化(指针类型)
package main
import "fmt"
type Student struct {
id int
name string
}
func main() {
// 使用 & 进行实例化
stu := &Student{id: 1, name: "luobozi"}
fmt.Println((*stu).name) // 通过指针访问字段
fmt.Println(stu.name) // 语法糖,自动解引用
}
结构体实例化(值类型)
package main
import "fmt"
type Student struct {
id int
name string
}
func main() {
// 值类型实例化 不加 & 符号
stu := Student{id: 1, name: "luobozi"}
fmt.Println(stu)
}
使用 new 进行实例化
new(T)
分配 T 类型的零值 并返回 指向该零值的指针 *T
。
适用于 值类型(如 struct、array 等)。
只分配内存,不进行额外初始化。
package main
import "fmt"
type Student struct {
name string
age int
}
func main() {
stu := new(Student) // 分配 Student 类型的零值
fmt.Printf("%+v\n", stu) // 输出:&{name: age:0}
stu.name = "Alice"
stu.age = 20
fmt.Printf("%+v\n", stu) // 输出:&{name:Alice age:20}
}
结构体的值传递与指针传递
package main
import "fmt"
type Student struct {
id int
name string
age int
}
func test(s Student) {
fmt.Println("传递值")
s.age = 100
}
func test1(s *Student) {
fmt.Println("传递指针")
s.age = 200
}
func main() {
stu := Student{id: 1, name: "luobozi", age: 18}
test(stu)
fmt.Println("调用 test 后:", stu)
test1(&stu)
fmt.Println("调用 test1 后:", stu)
}
结构体方法(值接收者和指针接收者)
package main
import "fmt"
type Student struct {
name string
}
func (s Student) ChangeName(name string) {
fmt.Println("值接收者:", name)
s.name = name
}
func (s *Student) ChangeName2(name string) {
fmt.Println("指针接收者:", name)
s.name = name
}
func main() {
stu := Student{name: "luobozi"}
stu.ChangeName("Alice") // 不会修改原数据
fmt.Println(stu)
stu.ChangeName2("Bob") // 会修改原数据
fmt.Println(stu)
}
匿名结构体
package main
import "fmt"
func main() {
anon := struct {
id int
addr string
}{id: 10, addr: "长沙"}
fmt.Println(anon)
}
匿名字段
package main
import "fmt"
type Person struct {
string
int
}
func main() {
p := Person{"匿名", 20}
fmt.Println(p)
}
空结构体
package main
import "fmt"
type Empty struct{}
func (e *Empty) Call() {
fmt.Println("调用空结构体方法")
}
func main() {
var e Empty
e.Call()
}
空结构体用于集合
package main
import "fmt"
type Set map[string]struct{} //使用map为基本,创建set类型
func (s Set) Add(k string) {
s[k] = struct{}{} //空结构体是不占用内存的,所以就用这种方式实现集合,本质上也是一个map
}
func main() {
s := make(Set)
s.Add("Go")
s.Add("Python")
fmt.Println(s)
}
结构体内存对齐
package main
import (
"fmt"
"unsafe"
)
type A struct {
a int8
b int64
c int8
}
type B struct {
a int8
c int8
b int64
}
func main() {
fmt.Println("结构体 A 大小:", unsafe.Sizeof(A{})) //结构体 A 大小: 24
fmt.Println("结构体 B 大小:", unsafe.Sizeof(B{})) //结构体 B 大小: 16
}