golang接口用法之:结构体内嵌匿名接口

文章通过一个计算器的例子展示了在Golang中如何使用结构体内嵌匿名接口来重写部分方法。当需要修改实现了接口的结构体的某一个方法而不影响其他方法时,可以创建一个新的结构体,内嵌原接口并重写所需方法。这种方式避免了重复实现接口的所有方法,提高了代码复用和维护性。

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

前言

在golang中,【结构体】内嵌【结构体】、【接口】内嵌【接口】经常见,但【结构体】内嵌 【匿名接口】可能会见得比较少,有什么场景可以这种用法呢?

当我们需要重写一个 “实现了某个接口的结构体” 的部分方法,而其它方法保持不变 的时候,就需要用到这种用法。

下面以计算器为例子进行说明。

代码

定义一个计算器接口,拥有 “加法” 和 “乘法” 两个方法,并定义一个结构体实现这个接口,代码如下:

package main

import "fmt"

type Icalculator interface {
	sum(a, b int) int      // 加法
	multiply(a, b int) int // 乘法
}

// 定义 MyCalc 结构体,并实现 Icalculator 接口中的方法
type MyCalc struct{}

func (obj MyCalc) sum(a, b int) int {
	return a + b
}

func (obj MyCalc) multiply(a, b int) int {
	return a * b
}

func main() {
	myCalc := MyCalc{}

	a, b := 5, 3
	fmt.Printf("sum: %d, multiply: %d\n", myCalc.sum(a, b), myCalc.multiply(a, b))
	// 输出:sum: 8, multiply: 15
}

至此,我们已经拥有了一个计算器结构体,并可以正常使用。

但假设我们现在有一个需求,需要改写MyCalcsum方法,将加法改成减法,并且乘法方法保持不变,这时候可以怎么做呢?

当然,我们可以新增一个结构体,重新实现接口中的所有方法来达到这个目标,但是如果这个接口中有很多方法呢,全部重新实现一遍就太过小事大做了,而且我们只是想重写sum方法而已,其它方法保持不变。

那么,这时候就需要用到 【结构体】 内嵌 【匿名接口】 的用法了,代码如下:

package main

import "fmt"

type Icalculator interface {
	sum(a, b int) int      // 加法
	multiply(a, b int) int // 乘法
}

// 定义 MyCalc 结构体,并实现 Icalculator 接口中的方法
type MyCalc struct{}

func (obj MyCalc) sum(a, b int) int {
	return a + b
}

func (obj MyCalc) multiply(a, b int) int {
	return a * b
}

// 新增定义一个 CustomCalc 结构体,并匿名内嵌 Icalculator 接口
type CustomCalc struct {
	Icalculator
}

// 改写sum方法
func (obj CustomCalc) sum(a, b int) int {
	return a - b
}

func main() {
	myCalc := MyCalc{}
	// 将myCalc传入CustomCalc结构体
	customCalc := CustomCalc{myCalc}

	a, b := 5, 3
	fmt.Printf("sum: %d, multiply: %d\n", customCalc.sum(a, b), customCalc.multiply(a, b))
	// 输出:sum: 2, multiply: 15
}

我们通过新增一个CustomCalc结构体,并在初始化的时候将myCalc传入,CustomCalc结构体定义一个sum方法,这个sum方法会覆盖myCalc的同名方法,从而实现了sum方法的重写。

总结

结构体内嵌接口的作用:

  • 不依赖具体实现:即接口为A,结构体B1、B2实现了接口A,结构体C内嵌了A,那么C.A可以通过B1/B2实例化;
  • 对接口类型进行重写:当C.A通过B1实例化后,C和B1的关系,可以转变为结构体C内嵌结构体B1,那么C可以直接使用B1中的所有方法,当然C也可以对B1中的方法进行重写,这里官方文档这样解释“Interface and we can override a specific method without having to define all the others.”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值