0

0

Go 语言结构体(Struct)与面向对象编程实践

DDD

DDD

发布时间:2025-10-16 12:12:19

|

396人浏览过

|

来源于php中文网

原创

go 语言结构体(struct)与面向对象编程实践

本文旨在帮助初学者理解 Go 语言中结构体(Struct)的使用,并将其与面向对象编程的概念相结合。通过构建一个简单的汽车(Car)示例,我们将深入探讨方法(Methods)中指针与值的区别,以及如何正确地修改结构体内部状态,从而实现预期的程序行为。

Go 语言虽然不是严格意义上的面向对象编程语言,但它提供了结构体(Struct)和方法(Methods)的概念,允许开发者以面向对象的方式组织和管理代码。本教程将通过一个汽车(Car)的例子,演示如何在 Go 语言中使用结构体来模拟对象,并解决在方法调用中遇到的值传递问题。

结构体的定义与使用

首先,我们定义两个结构体:Car 和 Engine。Car 结构体包含汽车的品牌(Make)、型号(Model)和一个 Engine 类型的字段。Engine 结构体包含气缸数(Cylinders)和启动状态(Started)。

package main

import (
    "fmt"
)

type Engine struct {
    Cylinders int
    Started   bool
}

type Car struct {
    Make   string
    Model  string
    Engine Engine
}

方法的定义与调用

接下来,我们为 Engine 结构体定义两个方法:Start() 和 IsStarted()。Start() 方法用于启动引擎,IsStarted() 方法用于检查引擎是否已启动。

关键问题:指针接收者 vs. 值接收者

在 Go 语言中,方法可以有值接收者(value receiver)或指针接收者(pointer receiver)。这决定了方法是否能够修改接收者(即结构体实例)的状态。

  • 值接收者: 方法接收的是结构体实例的副本。在方法内部对接收者的修改不会影响原始结构体实例。
  • 指针接收者: 方法接收的是结构体实例的指针。在方法内部对接收者的修改会直接影响原始结构体实例。

在我们的例子中,Start() 方法需要修改 Engine 结构体的 Started 字段。因此,我们必须使用指针接收者。

func (e *Engine) Start() {
    fmt.Println("Inside the Start() func, started starts off", e.Started)
    e.Started = true
    fmt.Println("Inside the Start() func, then turns to", e.Started)
}

func (e *Engine) IsStarted() bool {
    return e.Started
}

注意 Start() 和 IsStarted() 方法的接收者类型是 *Engine,而不是 Engine。

知我AI
知我AI

一款多端AI知识助理,通过一键生成播客/视频/文档/网页文章摘要、思维导图,提高个人知识获取效率;自动存储知识,通过与知识库聊天,提高知识利用效率。

下载

完整的示例代码

下面是完整的示例代码:

package main

import (
    "fmt"
)

type Engine struct {
    Cylinders int
    Started   bool
}

func (e *Engine) Start() {
    fmt.Println("Inside the Start() func, started starts off", e.Started)
    e.Started = true
    fmt.Println("Inside the Start() func, then turns to", e.Started)
}

func (e *Engine) IsStarted() bool {
    return e.Started
}

type Car struct {
    Make   string
    Model  string
    Engine Engine
}

func (c *Car) Start() {
    fmt.Println("starting engine ...")
    c.Engine.Start()
    fmt.Println("you'd think it would be started here ...", c.Engine)
}


func main() {
    car := Car{
        Make:  "AMC",
        Model: "Gremlin",
    }
    fmt.Printf("I'm going to work now in my %s %s\n", car.Make, car.Model)

    fmt.Println("I guess I should start my car.")
    carPtr := &car // 获取 car 的指针
    carPtr.Start()
    fmt.Println("Engine started?", car.Engine.IsStarted())
}

在这个例子中,Car 结构体的 Start 方法也需要修改 Engine 结构体的状态,因此也使用了指针接收者。

运行结果

运行上述代码,将得到以下输出:

I'm going to work now in my AMC Gremlin
I guess I should start my car.
starting engine ...
Inside the Start() func, started starts off false
Inside the Start() func, then turns to true
you'd think it would be started here ... {0 true}
Engine started? true

可以看到,引擎成功启动,IsStarted() 方法返回 true。

初始化

Go 语言没有传统的构造函数。通常使用函数来返回结构体的实例。 可以设置默认值。

package main

import "fmt"

type Engine struct {
    Cylinders int
    Started   bool
}

func NewEngine() *Engine {
    return &Engine{
        Cylinders: 4, // 默认4缸
        Started:   false,
    }
}

type Car struct {
    Make   string
    Model  string
    Engine *Engine
}

func NewCar(make, model string) *Car {
    return &Car{
        Make:   make,
        Model:  model,
        Engine: NewEngine(), // 使用默认引擎
    }
}

func main() {
    myCar := NewCar("Toyota", "Corolla")
    fmt.Println(myCar.Engine.Cylinders) // 输出: 4
}

总结

通过本教程,我们学习了如何在 Go 语言中使用结构体和方法来模拟面向对象编程。关键在于理解指针接收者和值接收者的区别,并根据需要选择合适的接收者类型,以便正确地修改结构体的内部状态。此外,还学习了如何使用函数来初始化结构体,并设置默认值。

注意事项:

  • 始终考虑方法是否需要修改接收者的状态。如果需要,请使用指针接收者。
  • 理解 Go 语言中的指针概念对于编写正确的代码至关重要。
  • Go 语言的面向对象编程方式与传统的面向对象编程语言有所不同,需要适应其独特的语法和特性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

65

2025.11.27

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

510

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

204

2025.07.04

java值传递和引用传递有什么区别
java值传递和引用传递有什么区别

java值传递和引用传递的区别:1、基本数据类型的传递;2、对象的传递;3、修改引用指向的情况。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

109

2024.02.23

chatgpt官网入口地址合集
chatgpt官网入口地址合集

本专题整合了chatgpt官网入口地址、使用教程等内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

minimax入口地址汇总
minimax入口地址汇总

本专题整合了minimax相关入口合集,阅读专题下面的文章了解更多详细地址。

4

2026.03.16

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

7

2026.03.16

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

114

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.3万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号