Go 语言中的结构体

GolangBeginner
立即练习

介绍

结构体(struct)是一种复合类型,可用于存储不同类型的数据。它可以用来实现更复杂的数据结构。例如,便利店中的商品具有产品名称、类别和价格等属性。我们可以使用结构体来表示它们。

在本实验中,我们将学习如何定义和使用结构体。

知识点:

  • 结构体的定义
  • 结构体实例的方法
这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 100%。获得了学习者 100% 的好评率。

结构体的定义

我们可以使用关键字 typestruct 来定义一个结构体。语法如下:

type StructName struct {
    FieldName Type
    // ...
}

其中:

  • Type 表示字段名称的具体类型,可以是整数、字符串等。
  • StructName 必须在同一个包内唯一。
  • 字段名称 必须在同一个结构体内唯一。

让我们来尝试一下。我们定义一个便利店:

type Store struct {
    ProductType string // 产品类型
    ProductName string // 产品名称
    Price       int    // 产品价格
}

在上面的代码中,我们为便利店定义了一个名为 Store 的结构体,其中包含产品的类型、名称和价格。

由于产品类型和产品名称字段的类型相同,我们可以将代码简化为如下形式:

type Store struct {
    ProductName, ProductType string
    Price                   int
}

使用 var 进行实例化

在上一节中,我们定义了一个便利店结构体 Store,它描述了内存空间。只有在实例化后,才会分配内存并使用结构体的字段。

我们可以使用 var 关键字来实例化一个结构体:

var InstanceName Structure

让我们来看一个实例化的例子。创建一个名为 struct.go 的文件,并编写以下代码:

cd ~/project
touch struct.go
package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    // 使用 `var` 实例化一个结构体
    var store1 Store
    // 为实例 store1 的相关字段赋值
    store1.productType = "Drinks"
    store1.productName = "Coca-Cola"
    store1.price = 3

    fmt.Printf("store1:\n\t%s\n\t%s\n\t%d\n",
        store1.productType, store1.productName, store1.price)
}

运行程序:

go run struct.go

运行后,显示以下结果:

store1:
Drinks
Coca-Cola
3

在这个程序中,我们使用 var 实例化了一个便利店,然后使用 . 操作符为其字段赋值。

结构体的初始值

如果我们只初始化一个结构体而不赋值,其实例化后的值会是什么?让我们来看以下代码:

package main

import "fmt"

type Store struct {
    ProductName string
    ProductType string
    Price       int
}

func main() {
    // 使用 `var` 实例化一个结构体
    var lan1 Store
    // 使用 %#v 打印结构体的值
    fmt.Printf("lan1: %#v\n", lan1)
}

运行程序:

go run struct.go

结果如下:

lan1: main.Store{ProductName:"", ProductType:"", Price:0}

我们可以看到,当没有指定初始值时,实例化的结构体的值是对应类型的零值。例如,字符串为空,整数为 0。

使用 new 进行实例化

除了使用 var 关键字进行实例化外,我们还可以使用 new 关键字:

package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    store := new(Store)
    // 使用 %T 输出类型
    fmt.Printf("Type of store: %T\n", store)

    store.productType = "Daily Necessities"
    store.productName = "Umbrella"
    store.price = 20

    fmt.Printf("store:\n\t%s\n\t%s\n\t%d\n",
        store.productType, store.productName, store.price)
}

运行程序:

go run struct.go

结果如下:

Type of store: *main.Store
store:
        Daily Necessities
        Umbrella
        20

当使用 new 关键字进行实例化时,它创建的“实例”实际上是指向实例的指针。对结构体指针的赋值操作与对普通结构体的赋值操作相同。

使用 := 进行实例化

同样地,我们可以使用 := 来实例化一个结构体:

package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    lan3 := Store{}
    lan3.productType = "Fresh Food"
    lan3.productName = "Taiwanese Meatballs"
    lan3.price = 20
    fmt.Printf("lan3:\n\t%s\n\t%s\n\t%d\n",
        lan3.productType, lan3.productName, lan3.price)
}

运行程序:

go run struct.go

结果如下:

lan3:
    Fresh Food
    Taiwanese Meatballs
    20

我们可以将初始化赋值写在一起,像这样:

package main

import "fmt"

type Store struct {
    productName string
    productType string
    price       int
}

func main() {
    lan3 := Store{
        productType: "Fresh Food",
        productName: "Taiwanese Meatballs",
        price:       4,
    }
    fmt.Printf("lan3:\n\t%s\n\t%s\n\t%d\n",
        lan3.productType, lan3.productName, lan3.price)
}

运行程序:

go run struct.go

结果如下:

lan3:
    Fresh Food
    Taiwanese Meatballs
    4

当我们需要为结构体的所有字段赋值时,可以按照结构体中字段定义的顺序来写值。

例如,我们可以将 lan3 实例重写如下:

lan3 := Store{
        "Fresh Food",
        "Taiwanese Meatballs",
        4,
    }

注意:这种语法仅适用于为所有字段赋值的情况。

总结

在本实验中,我们介绍了结构体并总结了以下知识点:

  • 结构体是复合数据类型,可以包含多个不同的数据类型。
  • 未初始化的结构体的值是对应类型的零值。
  • 实例化结构体的三种方法。