结构体
基本结构体
Go语言中结构体的基本定义和使用。
// 定义结构体
type Person struct {
Name string
Age int
Email string
Address string
}
// 创建结构体实例
func main() {
// 方式1:按字段顺序
p1 := Person{"张三", 25, "zhangsan@example.com", "北京市"}
// 方式2:指定字段名
p2 := Person{
Name: "李四",
Age: 30,
Email: "lisi@example.com",
Address: "上海市",
}
// 方式3:使用new
p3 := new(Person)
p3.Name = "王五"
p3.Age = 35
// 访问字段
fmt.Println(p1.Name) // 输出:张三
fmt.Println(p2.Age) // 输出:30
fmt.Println(p3.Email) // 输出:空字符串
}
结构体方法
为结构体定义方法。
// 值接收者方法
func (p Person) GetName() string {
return p.Name
}
// 指针接收者方法
func (p *Person) SetAge(age int) {
p.Age = age
}
// 使用示例
func main() {
p := Person{Name: "张三", Age: 25}
// 调用值接收者方法
name := p.GetName()
// 调用指针接收者方法
p.SetAge(26)
fmt.Println(name) // 输出:张三
fmt.Println(p.Age) // 输出:26
}
结构体标签
使用结构体标签进行元数据标记。
type User struct {
ID int `json:"id" db:"user_id"`
Name string `json:"name" db:"user_name"`
Email string `json:"email" db:"email"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
// 使用反射读取标签
func main() {
u := User{
ID: 1,
Name: "张三",
Email: "zhangsan@example.com",
CreatedAt: time.Now(),
}
// 获取结构体类型
t := reflect.TypeOf(u)
// 遍历字段
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fmt.Printf("字段: %s\n", field.Name)
fmt.Printf("JSON标签: %s\n", field.Tag.Get("json"))
fmt.Printf("DB标签: %s\n", field.Tag.Get("db"))
}
}
嵌套结构体
结构体的嵌套和组合。
// 基础结构体
type Address struct {
City string
Street string
ZipCode string
}
// 嵌套结构体
type Employee struct {
Name string
Age int
Address Address // 嵌套Address结构体
}
// 匿名嵌套
type Manager struct {
Employee // 匿名嵌套Employee
Department string
Level int
}
func main() {
// 创建Employee实例
emp := Employee{
Name: "张三",
Age: 30,
Address: Address{
City: "北京",
Street: "朝阳区",
ZipCode: "100000",
},
}
// 创建Manager实例
mgr := Manager{
Employee: Employee{
Name: "李四",
Age: 35,
Address: Address{
City: "上海",
Street: "浦东新区",
ZipCode: "200000",
},
},
Department: "技术部",
Level: 2,
}
// 访问嵌套字段
fmt.Println(emp.Address.City) // 输出:北京
fmt.Println(mgr.City) // 输出:上海(通过匿名嵌套直接访问)
}
结构体最佳实践
结构体使用的最佳实践和注意事项。
# 1. 字段命名
- 使用驼峰命名法
- 首字母大写表示公开字段
- 首字母小写表示私有字段
# 2. 方法接收者选择
- 如果方法需要修改结构体,使用指针接收者
- 如果方法不需要修改结构体,使用值接收者
- 考虑性能影响,大型结构体使用指针接收者
# 3. 结构体标签
- 使用标准标签格式
- 保持标签的一致性
- 使用有意义的标签名
# 4. 嵌套结构体
- 使用组合而不是继承
- 合理使用匿名嵌套
- 注意字段访问的优先级
# 5. 构造函数
- 提供构造函数创建结构体实例
- 在构造函数中进行初始化
- 返回指针而不是值
# 示例
type Config struct {
Host string
Port int
Timeout time.Duration
MaxRetry int
}
// 构造函数
func NewConfig(host string, port int) *Config {
return &Config{
Host: host,
Port: port,
Timeout: 30 * time.Second,
MaxRetry: 3,
}
}