Go 语言中的结构体类型#
1. 定义与实例化#
// 定义一个 User 结构体
type User struct {
Name string
Age int
Email string
}
// 多种实例化方式
func main() {
// 方式 1
u1 := User{
Name: "Bob",
Age: 30,
Email: "bob@example.com",
}
// 方式 2
u2 := new(User) // 返回指针,字段初始化为零值
u2.Name = "Charlie"
// 方式 3:& 取地址
u3 := &User{Name: "David"}
}2. 结构体的零值#
结构体的零值是其所有字段为零值的组合:
type Config struct {
Host string
Port int
Enabled bool
}
func main() {
var config Config
fmt.Printf("Host: %q, Port: %d, Enabled: %v\n",
config.Host, config.Port, config.Enabled)
// 输出:Host: "", Port: 0, Enabled: false
}3. 赋值和传参#
赋值和传参都会复制整个结构体。如果需要修改原值或避免大结构体复制带来的开销,使用指针。
func main() {
u1 := User{Name: "Bob", Age: 30}
modifyByValue(u1)
fmt.Println(u1.Name) // 输出:Bob,原值未被修改
modifyByPointer(&u1)
fmt.Println(u1.Name) // 输出:David,指针可以修改原值
}
func modifyByValue(u User) {
u.Name = "Charlie"
}
func modifyByPointer(u *User) {
u.Name = "David"
}4. 方法定义#
Go 的方法可以定义在值接收者或指针接收者上:
type Rectangle struct {
Width, Height float64
}
// 值接收者:不会修改原值
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// 指针接收者:可以修改原值
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
//指针接收者:可以避免大结构体复制带来的性能开销
func (r *Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}- 如果需要修改接收者,选择指针接收者;
- 如果结构体很大,选择指针接收者来避免复制;
- 如果结构体小而且不可变,选择值接收者。