Go 语言的结构体(struct)是一种聚合数据类型,可以将不同类型的数据组合在一起。结构体允许你在同一个类型中封装多个不同类型的数据,从而更好地组织复杂数据。

Go 语言的结构体是非常强大的,它们可以包含不同的字段,每个字段都可以是不同的数据类型。结构体广泛应用于表示复杂的对象或实体。


📖 目录

  1. 结构体简介
  2. 定义结构体
  3. 访问结构体字段
  4. 结构体指针
  5. 结构体与方法
  6. 匿名结构体
  7. 结构体嵌套
  8. 结构体与 JSON
  9. 参考资料

1. 结构体简介

结构体(struct)是 Go 语言中用于定义数据类型的关键字,它允许将多个不同类型的数据组合在一起。这些数据项称为字段。每个字段有自己的名字和类型,可以是任何有效的数据类型。

结构体通常用于表示对象或实体,例如表示一个“学生”可以使用包含姓名、年龄、成绩等字段的结构体。


2. 定义结构体

定义结构体的语法如下:

type StructName struct {
    Field1 Type1
    Field2 Type2
    Field3 Type3
}

  • StructName:结构体的名称。
  • Field1, Field2, Field3:结构体字段的名称。
  • Type1, Type2, Type3:字段的数据类型。

示例:

package main

import "fmt"

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

func main() {
    // 创建结构体实例并赋值
    p1 := Person{Name: "John", Age: 30}
    fmt.Println(p1) // 输出: {John 30}
}

在上面的示例中,定义了一个 Person 结构体,包含了两个字段:Name(字符串类型)和 Age(整数类型)。在 main 函数中,创建了一个 Person 类型的实例,并为字段赋值。


3. 访问结构体字段

可以通过结构体的实例访问其字段,使用 . 运算符:

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{Name: "John", Age: 30}

    // 访问字段
    fmt.Println("Name:", p.Name) // 输出: Name: John
    fmt.Println("Age:", p.Age)   // 输出: Age: 30
}


4. 结构体指针

你也可以使用结构体的指针。通过指针,你可以修改结构体的值。

示例:

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    p := &Person{Name: "John", Age: 30}

    // 访问字段(通过指针)
    fmt.Println("Name:", p.Name) // 输出: Name: John
    fmt.Println("Age:", p.Age)   // 输出: Age: 30

    // 修改字段
    p.Age = 35
    fmt.Println("Updated Age:", p.Age) // 输出: Updated Age: 35
}


5. 结构体与方法

在 Go 中,结构体可以与方法结合使用,从而创建对象的行为。方法与结构体的字段有相同的作用,方法通过结构体来实现功能。

示例:

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

// 定义方法
func (p *Person) Greet() {
    fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}

func main() {
    p := &Person{Name: "John", Age: 30}

    // 调用方法
    p.Greet() // 输出: Hello, my name is John and I am 30 years old.
}

在上面的代码中,GreetPerson 结构体的方法,它通过结构体实例的指针来操作和打印结构体的字段。


6. 匿名结构体

Go 允许你创建匿名结构体,即没有给结构体命名的结构体。这些结构体通常用于临时存储数据或在函数中作为参数。

示例:

package main

import "fmt"

func main() {
    // 创建一个匿名结构体实例
    p := struct {
        Name string
        Age  int
    }{
        Name: "John",
        Age:  30,
    }

    fmt.Println(p) // 输出: {John 30}
}

匿名结构体适用于仅在特定作用域内使用的结构体,可以在函数调用时传递数据,而不需要定义一个明确的类型。


7. 结构体嵌套

Go 语言支持结构体嵌套,即一个结构体中可以包含另一个结构体。这种方式通常用于表示更复杂的层次结构。

示例:

package main

import "fmt"

// 定义一个 Address 结构体
type Address struct {
    Street string
    City   string
    Zip    string
}

// 定义一个 Person 结构体,其中嵌套 Address 结构体
type Person struct {
    Name    string
    Age     int
    Address Address
}

func main() {
    p := Person{
        Name: "John",
        Age:  30,
        Address: Address{
            Street: "123 Main St",
            City:   "New York",
            Zip:    "10001",
        },
    }

    // 访问嵌套结构体的字段
    fmt.Println("Name:", p.Name)
    fmt.Println("Street:", p.Address.Street)
    fmt.Println("City:", p.Address.City)
}

在这个例子中,Person 结构体嵌套了 Address 结构体,可以直接访问嵌套结构体的字段。


8. 结构体与 JSON

Go 提供了 encoding/json 包,用于将结构体与 JSON 数据互相转换。通过使用结构体标签,你可以定义 JSON 字段与 Go 结构体字段之间的映射关系。

示例:

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    p := Person{Name: "John", Age: 30}

    // 结构体转 JSON
    jsonData, err := json.Marshal(p)
    if err != nil {
        fmt.Println("Error marshaling:", err)
    }
    fmt.Println("JSON:", string(jsonData))

    // JSON 转结构体
    jsonStr := `{"name":"John", "age":30}`
    var p2 Person
    err = json.Unmarshal([]byte(jsonStr), &p2)
    if err != nil {
        fmt.Println("Error unmarshaling:", err)
    }
    fmt.Println("Decoded Struct:", p2)
}


9. 参考资料


通过以上示例和概念,你可以更好地理解 Go 语言的结构体,并能在实际开发中应用它们。结构体是 Go 中重要的基础数据结构,它帮助我们更好地组织和管理复杂数据。