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。

Napkin AI
Napkin AI

Napkin 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 语言的面向对象编程方式与传统的面向对象编程语言有所不同,需要适应其独特的语法和特性。

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

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

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

54

2025.09.05

java面向对象
java面向对象

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

46

2025.11.27

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

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

193

2025.06.09

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

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

186

2025.07.04

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

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

106

2024.02.23

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

65

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

45

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

40

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

41

2025.12.31

热门下载

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

精品课程

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

共32课时 | 3.2万人学习

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

共10课时 | 0.8万人学习

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

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