结构体与方法
约 845 字大约 3 分钟
2025-04-23
结构体声明与初始化
基本声明
type boy struct {
name string
age int
}初始化方式
// 方式1:键值对初始化(推荐)
b1 := boy{
name: "zhangsan",
age: 18,
}
// 方式2:按顺序直接赋值
b2 := boy{
"lisi",
20,
}提示
当结构体数据量少时用值传递;数据量大时使用指针传递以提高性能。
匿名结构体
没有显式类型名称的结构体,用于临时或一次性的数据组合场景:
// 方式1:先声明再赋值
var user struct {
name string
age int8
}
user.name = "lisi"
// 方式2:声明并初始化
var dog = struct {
name string
age int8
color string
}{
name: "lucky",
age: 3,
color: "black",
}结构体嵌套
type address struct {
province string
city string
}
type person struct {
name string
gender string
age int8
address address // 嵌套另一个结构体
}
func main() {
p1 := person{
name: "张三",
gender: "男",
age: 20,
address: address{
province: "山东",
city: "德州",
},
}
fmt.Println(p1)
}匿名嵌套(继承式)
type animal struct {
name string
}
type dog struct {
feet int8
*animal // 匿名字段(指针类型)
}
func (a *animal) move() {
fmt.Printf("%s 会动\n", a.name)
}
func (d *dog) wang() {
fmt.Printf("%s 会叫\n", d.name)
}
func main() {
d1 := dog{
feet: 4,
animal: &animal{name: "lucky"},
}
d1.move() // lucky 会动
d1.wang() // lucky 会叫
}选项模式(Options Pattern)
通过函数选项的方式灵活初始化结构体,避免构造函数参数过多:
type Person struct {
Name string
Age int
Address string
Salary float64
}
// 定义选项函数类型
type PersonOptions func(p *Person)
// 创建选项函数(以 With 开头)
func WithName(name string) PersonOptions {
return func(p *Person) { p.Name = name }
}
func WithAge(age int) PersonOptions {
return func(p *Person) { p.Age = age }
}
func WithAddress(address string) PersonOptions {
return func(p *Person) { p.Address = address }
}
func WithSalary(salary float64) PersonOptions {
return func(p *Person) { p.Salary = salary }
}
// 构造函数
func NewPerson(options ...PersonOptions) *Person {
p := &Person{}
for _, option := range options {
option(p)
}
// 默认值处理
if p.Age < 0 { p.Age = 0 }
if p.Salary < 0 { p.Salary = 0 }
return p
}
func main() {
p1 := NewPerson(
WithName("Tom"),
WithAge(23),
WithAddress("66 London"),
WithSalary(10000.0),
)
fmt.Println(p1)
}new 与 make 的区别
| 特性 | new | make |
|---|---|---|
| 适用类型 | 值类型(struct, int 等) | 引用类型(slice, map, channel) |
| 返回值 | 指向零值的指针 | 已初始化的值(非指针) |
| 初始化 | 分配内存,返回零值指针 | 分配内存并初始化底层数据结构 |
// map 和 struct 的 new() 和 make()
// 对于值类型,new 返回的是零值的指针,有分配内存
// 对于引用类型,new 返回的零值是 nil,此时不能直接赋值
// 正确做法:使用 make 初始化
m := make(map[string]int) // map
s := make([]int, 5) // slice
ch := make(chan int) // channel方法
方法是作用在指定类型上的函数,只有自定义类型能够拥有方法。
type person struct {
name string
age int8
}
// 方法定义:func (接收者 类型) 方法名(参数) 返回值
func (p person) com() {
fmt.Printf("%s 的年龄是 %d\n", p.name, p.age)
}
func main() {
p1 := person{"小明", 18}
p2 := person{age: 20, name: "Tom"}
p1.com() // 小明的年龄是 18
p2.com() // Tom 的年龄是 20
}自定义类型的方法
方法不仅仅可以绑定到结构体,任何自定义类型都可以:
type MyIntArray []int
// 为自定义类型添加方法
func (m MyIntArray) Get(index int) int {
return m[index]
}
func main() {
myint := MyIntArray{2, 4, 6, 8, 10}
fmt.Println(myint.Get(3)) // 8
}方法 vs 函数
- 方法有接收者(receiver),函数没有
- 方法调用:
变量.方法名() - Go 推荐使用接收者类型名称的首字母小写(如
MyInt→m)
