Go 语言结构(Struct)详解
                           
天天向上
发布: 2025-03-25 23:32:40

原创
416 人浏览过

在 Go 语言中,struct(结构体)是一种复合数据类型,用于将多个不同类型的数据组合在一起。它类似于 C 语言中的 struct 或 Java 中的 class(但 Go 语言没有类的概念)。


1. 结构体的定义

Go 语言使用 type 关键字定义结构体,struct 关键字用于声明结构体类型。例如:

package main

import "fmt"

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

func main() {
    // 创建结构体实例
    p := Person{"Alice", 25, "Beijing"}
    fmt.Println(p)
}

输出:

{Alice 25 Beijing}

2. 结构体的初始化

Go 语言支持多种方式初始化结构体实例。

(1)使用字面量初始化

p1 := Person{"Bob", 30, "Shanghai"} // 顺序匹配字段
p2 := Person{Name: "Tom", Age: 28}  // 使用字段名初始化(部分字段)

(2)使用 new 关键字

p3 := new(Person) // 返回指针 *Person,字段默认值
p3.Name = "Mike"
p3.Age = 22

(3)使用 & 直接创建指针

p4 := &Person{"Emma", 26, "Guangzhou"} // 直接返回指针

3. 结构体字段

(1)匿名字段

Go 允许定义没有字段名称的结构体(匿名字段),该字段的类型即为名称。

type User struct {
    string
    int
}

u := User{"John", 25}
fmt.Println(u.string, u.int) // 访问方式

(2)嵌套结构体

结构体可以嵌套另一个结构体:

type Address struct {
    City  string
    State string
}

type Employee struct {
    Name    string
    Age     int
    Address // 匿名嵌套
}

e := Employee{"Jack", 35, Address{"New York", "NY"}}
fmt.Println(e.City) // 直接访问 Address 的字段

4. 结构体的方法

Go 允许在结构体上定义方法(方法是带有接收者的函数)。

type Rectangle struct {
    Width, Height float64
}

// 定义方法
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

rect := Rectangle{10, 5}
fmt.Println(rect.Area()) // 50

(1)指针接收者

使用指针接收者可以修改结构体内部值:

func (r *Rectangle) Scale(factor float64) {
    r.Width *= factor
    r.Height *= factor
}

这样 Scale 方法可以修改 Rectangle 实例的 WidthHeight


5. 结构体的 JSON 处理

Go 语言的 encoding/json 包允许结构体与 JSON 互转。

package main

import (
    "encoding/json"
    "fmt"
)

type Product struct {
    Name  string  `json:"name"`
    Price float64 `json:"price"`
}

func main() {
    p := Product{"Laptop", 1299.99}
    jsonData, _ := json.Marshal(p)
    fmt.Println(string(jsonData)) // {"name":"Laptop","price":1299.99}
}

(1)JSON 反序列化

var p2 Product
json.Unmarshal(jsonData, &p2)
fmt.Println(p2.Name, p2.Price)

6. 结构体的比较

结构体可以直接比较(所有字段可比较):

p1 := Person{"Alice", 25, "Beijing"}
p2 := Person{"Alice", 25, "Beijing"}
fmt.Println(p1 == p2) // true

7. 结构体与接口

Go 语言的接口可以用于结构体,实现多态特性:

type Shape interface {
    Area() float64
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return 3.14 * c.Radius * c.Radius
}

func main() {
    var s Shape = Circle{10}
    fmt.Println(s.Area()) // 314
}

8. 结构体标签(Struct Tags)

结构体字段可以使用标签(Tag)存储额外信息(常用于 JSON 解析、数据库 ORM)。

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name,omitempty"`
}
  • json:"name,omitempty" 表示如果 Name 为空,则 JSON 中不显示该字段。

9. 结构体与内存布局

结构体的字段会按照声明顺序排列,Go 会进行内存对齐优化:

type A struct {
    a int8  // 1 字节
    b int64 // 8 字节
    c int8  // 1 字节
}

为了减少内存占用,可以调整字段顺序:

type B struct {
    a int8  // 1 字节
    c int8  // 1 字节
    b int64 // 8 字节
}

10. 参考资料

发表回复 0

Your email address will not be published. Required fields are marked *