Skip to content

1.10 结构体与方法 ​

结构体定义与实例化 ​

go
package main

import "fmt"

// 结构体定义
type Person struct {
    Name string
    Age  int
    City string
}

// 匿名字段
type Employee struct {
    Person  // 匿名嵌入
    Company string
    Salary  float64
}

func main() {
    // 字面量
    p1 := Person{"Alice", 25, "Beijing"}
    p2 := Person{Name: "Bob", Age: 30}

    // new
    p3 := new(Person)
    p3.Name = "Carol"

    // 取地址
    p4 := &Person{Name: "David", Age: 35}

    fmt.Println(p1, p2, *p3, *p4)

    // 匿名嵌入的使用
    emp := Employee{
        Person:  Person{Name: "Eve", Age: 28},
        Company: "ACME",
    }
    fmt.Println(emp.Name)     // Eve
    fmt.Println(emp.Company)  // ACME
}

匿名字段与结构体嵌入 ​

go
package main

import "fmt"

type Address struct {
    City string
    Zip  string
}

type Contact struct {
    Email string
    Phone string
}

type User struct {
    Name    string
    Address  // 匿名嵌入
    Contact  // 匿名嵌入
}

// 字段冲突
type A struct {
    X int
}

type B struct {
    X int
}

type C struct {
    A
    B
}

func main() {
    user := User{
        Name:    "Alice",
        Address: Address{City: "Beijing"},
        Contact: Contact{Email: "alice@example.com"},
    }

    // 直接访问嵌入的字段
    fmt.Println(user.City)   // Beijing
    fmt.Println(user.Email)  // alice@example.com

    // 字段冲突处理
    c := C{}
    c.A.X = 1
    c.B.X = 2
    fmt.Println(c.A.X, c.B.X)
}

结构体标签 ​

go
package main

import (
    "encoding/json"
    "fmt"
    "reflect"
)

type User struct {
    ID       int     `json:"id" db:"user_id"`
    Name     string  `json:"name" validate:"required"`
    Email    string  `json:"email,omitempty"`
    Password string  `json:"-"`
}

func main() {
    user := User{ID: 1, Name: "Alice", Password: "secret"}

    // JSON 序列化
    data, _ := json.Marshal(user)
    fmt.Println(string(data))
    // {"id":1,"name":"Alice","email":""}

    // 反射读取标签
    t := reflect.TypeOf(user)
    field, _ := t.FieldByName("Name")
    fmt.Println(field.Tag.Get("json"))       // name
    fmt.Println(field.Tag.Get("validate"))   // required
}

方法定义 ​

go
package main

import "fmt"

type Counter struct {
    value int
}

// 值接收者
func (c Counter) Value() int {
    return c.value
}

// 指针接收者
func (c *Counter) Increment() {
    c.value++
}

func (c *Counter) Add(n int) {
    c.value += n
}

func main() {
    c := Counter{value: 0}
    fmt.Println(c.Value())  // 0

    c.Increment()
    fmt.Println(c.Value())  // 1

    c.Add(10)
    fmt.Println(c.Value())  // 11
}

Stringer 接口 ​

go
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s(%d)", p.Name, p.Age)
}

func main() {
    p := Person{Name: "Alice", Age: 25}
    fmt.Println(p)  // Alice(25) - 自动调用 String()
}