结构体

基本结构体

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,
    }
}