golang 组合和接口

本文介绍Go语言中如何通过组合实现类似面向对象继承的功能,并探讨接口的定义与使用,包括接口间的组合及其实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,组合

golang 中一切 皆是类型

这个和 面向对象的 概念有点像 ,但是又不太像,和javascript倒是有些相似之处

那么如何实现 像 Java中的 继承呢,golang使用的是组合

请看代码 和 运行输出 说明一切

type father struct {
name string
sex int
}
type sun struct {
father
name string
}
func main() {
s:=sun{father:father{name:"father",sex:11},name:"sun"}
fmt.Println(s)
fmt.Println("name",s.name)
fmt.Println("name",s.father.name)
fmt.Println("sex",s.sex)
fmt.Println("sex",s.father.sex)

}

=======================================

{{father 11} sun}
name sun

name father
sex 11
sex 11

===================================

father的sex属性就被组合进了sun ,成为了sun的属性,虽然我的 命名是 father和 sun但 二者不是继承 是组合的关系

当father的属性 和 sun的属性同名,被组合者 即母体 sun优先,想要 访问 father的name需要 s.father.name


二 .接口

//接口中可以组合其它接口,这种方式等效于在接口中添加其它接口的方法
type Reader interface {
read()
}
type Writer interface {
write()
}

//定义上述两个接口的实现类
type MyReadWrite struct{}

func (mrw *MyReadWrite) read() {
fmt.Println("MyReadWrite...read")
}

func (mrw *MyReadWrite) write() {
fmt.Println("MyReadWrite...write")
}

//定义一个接口,组合了上述两个接口
type ReadWriter interface {
Reader
Writer
}

//上述接口等价于:
type ReadWriterV2 interface {
read()
write()
}

//ReadWriter和ReadWriterV2两个接口是等效的,因此可以相互赋值
func interfaceTest0104() {
mrw := &MyReadWrite{}
//mrw对象实现了read()方法和write()方法,因此可以赋值给ReadWriter和ReadWriterV2
var rw1 ReadWriter = mrw
rw1.read()
rw1.write()

fmt.Println("------")
var rw2 ReadWriterV2 = mrw
rw2.read()
rw2.write()

//同时,ReadWriter和ReadWriterV2两个接口对象可以相互赋值
rw1 = rw2
rw2 = rw1
}


三.接口和组合

1.由于结构struct实现了接口的所有方法,所以可以将struct赋值给相应的接口
2.在 struct2中已经实现了对接口的所有的方法的实现
3.而struct1 如果组合的struct2了,那么struct1也就实现了接口的所有方法的实现,所以可以将struct1赋值给接口
### 使用 Golang Gin 框架连接 MySQL 创建 API 接口 #### 创建并配置项目结构 为了构建一个基于Gin框架的应用程序,首先需要初始化一个新的Go模块: ```bash go mod init example.com/gin-mysql-api ``` 接着安装必要的依赖包: ```bash go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/mysql ``` #### 初始化数据库连接 在 `main.go` 文件中设置MySQL数据库的连接字符串,并利用GORM建立与数据库之间的会话。 ```go package main import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" ) var db *gorm.DB var err error func InitDB() { dsn := "user:password@tcp(127.0.0.1:3306)/gin_demo?charset=utf8mb4&parseTime=True&loc=Local" db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { fmt.Println("Failed to connect database:", err) panic(err) } } ``` 这段代码展示了如何打开到名为 `gin_demo` 的MySQL数据库的连接[^1]。请注意替换DSN中的用户名、密码其他参数以匹配实际环境下的配置。 #### 定义模型层 (Model Layer) 假设要管理成员(`Member`)的数据,则可以在应用里定义相应的结构体来映射表字段。 ```go type Member struct { ID uint `json:"id"` Name string `json:"name" gorm:"not null"` Email string `json:"email" gorm:"uniqueIndex;not null"` CreatedAt time.Time UpdatedAt time.Time } ``` 此部分描述了实体类的设计原则及其属性约束条件[^2]。 #### 实现业务逻辑服务 (Service Layer) 编写服务于具体功能的服务函数,比如新增会员记录: ```go // CreateMember creates a new member record. func CreateMember(m *Member) (*Member, error) { result := db.Create(&m) if result.Error != nil { return nil, result.Error } return m, nil } ``` 上述片段说明了怎样封装基本的操作以便于后续调用。 #### 构建控制器 (Controller Layer) 最后一步是在HTTP请求处理器内实现对外暴露的功能端点。下面的例子实现了POST /members 路由用来接收客户端提交的新用户资料并保存至数据库。 ```go package controllers import ( "net/http" "github.com/gin-gonic/gin" ) func AddMember(c *gin.Context) { var input Member if err := c.ShouldBindJSON(&input); err == nil { createdMember, _ := service.CreateMember(&input) c.JSON(http.StatusOK, gin.H{"data": createdMember}) } else { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } } func SetupRoutes(engine *gin.Engine) { v1 := engine.Group("/api/v1") { members := v1.Group("/members") { members.POST("", AddMember) } } } ``` 以上内容解释了如何通过组合先前各层次组件完成一次完整的API交互过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值