每日一Go-6、Go语言结构体(Struct)与面向对象的实现方式

1、结构体的定义

go 复制代码
type [结构体名] struct{}
type Animal struct {
    Name    string
    Age     int
    Species string
    IsMammal bool
}

2、结构体初始化

结构体初始化有多种方式,首选命名字段的方式

go 复制代码
// 方式1:命名字段初始化(推荐)
dog := Animal{
    Name:    "丹尼",
    Age:     3,
    Species: "Dog",
    IsMammal: true,
}

// 方式2:顺序初始化(需注意字段顺序)
cat := Animal{"汤姆", 2, "Cat", true}

// 方式3:先声明后赋值
var bird Animal
bird.Name = "杰瑞"
bird.Species = "Rat"
bird.IsMammal = true

3、结构体的访问和嵌入结构体

使用 点号"." 操作符来访问结构体的字段

go 复制代码
fmt.Println(dog.Name) // 输出: 丹尼
cat.Age = 4 // 修改年龄

Go通过组合来扩展功能,可以在结构体中嵌入其他结构体,从而达到"继承"别的结构体的字段和方法的目的

go 复制代码
type Address struct {
    ZooName string
    City    string
}

// AnimalRecord 嵌入了 Animal 和 Address 结构体
type AnimalRecord struct {
    Animal         // 嵌入Animal,拥有其所有字段
    Address        // 嵌入Address,拥有其所有字段
    RecordID string
}
record := AnimalRecord{
    Animal: Animal{
        Name:    "辛巴",
        Age:     5,
        Species: "狮子",
        IsMammal: true,
    },
    Address: Address{
        ZooName: "北京动物园",
        City:    "Beijing",
    },
    RecordID: "A001",
}

// 可以直接访问嵌入结构的字段
fmt.Println(record.Name)    // 输出: 辛巴(来自嵌入的Animal)
fmt.Println(record.ZooName) // 输出: 北京动物园 (来自嵌入的Address)
fmt.Println(record.RecordID) // 输出: A001

4、为结构体定义方法

方法是与特定类型关联的函数。通过在func和方法名之间指定一个接收者,就可以给这个接收者定义一个方法

go 复制代码
// 值接收者方法:获取动物信息(不修改原数据)
func (a Animal) GetInfo() string {
    return fmt.Sprintf("%s 是一只%d岁的%s.", a.Name, a.Age, a.Species)
}
// 指针接收者方法:庆祝生日,修改年龄(需要修改原数据)
func (a *Animal) HaveBirthday() {
    a.Age++ // 这行修改会作用于原实例
    fmt.Printf("生日快乐, %s! 你现在%d岁了.\n", a.Name, a.Age)
}
fmt.Println(record.GetInfo())  
record.HaveBirthday()         
fmt.Println(record.GetInfo())  
//输出
//辛巴 是一只5岁的狮子.
//生日快乐, 辛巴! 你现在是6岁了.
//辛巴 是一只6岁的狮子.

5、嵌入结构体方法的使用

当一个结构体嵌入另一个结构体时,外部结构体就继承了内部结构体的字段和方法

go 复制代码
// AnimalRecord 可以直接使用 Animal 的方法
// 调用从 Animal 继承的方法
fmt.Println(record.GetInfo()) 
// 调用从 Animal 继承的指针方法,会修改嵌入的 Animal 数据
record.HaveBirthday() 

6、面向对象的实现

Go语言通过独特的方式支持面向对象的三大特性

  • 封装:字段和方法名,首字母大写是公开,首字母小写就是私有
  • 继承:通过结构体嵌入,外部结构体就可以复用内部结构体的字段和方法
  • 多态:Go语言通过接口(interface)实现多态,接口定义了一组方法,任何类型只要实现了接口的所有方法,就隐式地实现了该接口
go 复制代码
// 为 Animal 实现 Speaker 接口
func (a Animal) Speak() string {
    switch a.Species {
    case "Dog":
        return "旺旺!"
    case "Cat":
        return "喵~"
    default:
        return "这个动物出声了."
    }
}
// 函数接收接口类型,实现多态
func DoSpeak(s Speaker) {
    fmt.Println(s.Speak())
}
DoSpeak(dog) 
DoSpeak(cat) 
//输出
//旺旺!
//喵~

每个人都会有迷茫的时候,只要拨开云雾,勇往直前,风雨过后定能见到彩虹!

相关推荐
用户12961573585513 小时前
Go语言云原生与微服务架构终极实践指南
go
踏浪无痕14 小时前
Go 的协程是线程吗?别被"轻量级线程"骗了
后端·面试·go
程序员泡椒1 天前
二分查找Go版本实现
数据结构·c++·算法·leetcode·go·二分
且去填词1 天前
Go 语言的“反叛”——为什么少即是多?
开发语言·后端·面试·go
用户26851612107562 天前
GMP 调度器深度学习笔记
后端·go
Coding君2 天前
每日一Go-20、Go语言实战-利用Gin开发用户注册登录功能
go
用户26851612107562 天前
GMP 三大核心结构体字段详解
后端·go
corpse20102 天前
FastMonitor - 网络流量监控与威胁检测工具--各种报错!!!
go
源代码•宸5 天前
Leetcode—1929. 数组串联&&Q1. 数组串联【简单】
经验分享·后端·算法·leetcode·go
nil5 天前
记录protoc生成代码将optional改成omitepty问题
后端·go·protobuf