go语言函数/方法入参对象方法 接口interface约束示例

go语言使用泛型接口约束可以约束指定的对象参数 必须具备指定的方法 或者必须实现了指定的接口 1个或者多个接口(通过接口继承实现), 这个在面向api的接口编程中应用非常广泛,也非常实用,废话不多说,直接上代码:

泛型约束 接口 方法 接口继承 示例代码

//文件名 person.go
package genricargs

import "fmt"

// 泛型接口约束方法/函数形参,可以约束形参对象必须拥有指定的方法才能调用,
// 如 func SpeechDemo2[T interface {Speech() string; Exam()}](people T)
// 形参方法约束如果有多个可以每个一行或者在当行使用 分号 ; 隔开
// 这里的[T interface {Speech() string; Exam()}]约束的是 T中的方法,只要T中有这里指定的方法即可,
// 如果 T后面跟的 interface{ 方法定义1,方法定义2} 这表示T必须具备指定的方法, 如 [T interface {Speech() string; Exam()}]
// 如果 T后面跟的是接口,则说明T必须是实现指定的接口的对象, 如  [T Ability]
// 如果需要约束某个对象必须具备多个接口,则可以是继承的方式创建一个新的接口 然后继承需要约束的接口, 如 [T AB] 这里的AB就继承了2个接口 见后面代码

// 定义对象 用来存放数据
type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

// 定义Ability能力接口
type Ability interface {
	Speech() string //演讲方法
	Swim()          //游泳方法
}

// 为对象Person实现Ability接口
func (p *Person) Speech() string {
	return fmt.Sprintf("%v正在演讲", p.Name)
}
func (p *Person) Swim() {
	fmt.Printf("%v正在游泳\n", p.Name)
}

// Person的其他普通方法
func (p *Person) Exam() {
	fmt.Printf("%v正在考试\n", p.Name)
}

// 演讲测试
func SpeechDemo[T interface {
	Speech() string
	Swim()
}](people T) {
	str := people.Speech() // 因为T约束了这个people必须具备Speech这个方法,所以这里才可以直接调用
	fmt.Println(str)
	people.Swim()
}

// 约束people必须是拥有 Speech()和Exam()方法的对象,
func SpeechDemo2[T interface {
	Speech() string
	Exam()
}](people T) {
	str := people.Speech() // 因为T约束了这个people必须具备Speech这个方法,所以这里才可以直接调用
	fmt.Println(str)
	people.Exam()
}

// 这个当前的Person对象中没有Flight()方法, 调用直接编译错误
func SpeechDemo3[T interface {
	Speech() string
	Flight()
}](people T) {
	str := people.Speech() // 因为T约束了这个people必须具备Speech这个方法,所以这里才可以直接调用
	fmt.Println(str)
	people.Flight()
}

// 泛型参数直接约束接口, 当然这里的接口可以是多个 使用|分隔即可 ,如 [T Aaa| Bbb ]表示T必须是实现了Aaa或者Bbb
func SpeechDemo4[T Ability](people T) {
	str := people.Speech() // 因为T约束了这个people必须具备Speech这个方法,所以这里才可以直接调用
	fmt.Println(str)
	people.Swim()
	// people.Flight() //这行代码 直接编译错误 因为Ability接口中没有这个方法
}

type Bbb interface {
	Flight()
}

// 继承Ability和Bbb接口
type AB interface {
	Ability
	Bbb
}

// 这里使用了接口继承的方式来约束这里的people必须实现了 Ability接口和Bbb接口
func SpeechDemo5[T AB](people T) {
	str := people.Speech() // 因为T约束了这个people必须具备Speech这个方法,所以这里才可以直接调用
	fmt.Println(str)
	people.Swim()
	people.Flight()
}

单元测试用例

// person_test.go
package genricargs

import (
	"testing"
)

// 单元测试用例
// TestXxx和 ExampleXxx使用示例
// 这2种方法的区别在于Test需要带上参数 t *testing.T 而ExampleXxx则不需要, 带参数的TestXxx可以调用 t里面的一系列方法
// 他们都可以使用Output来指定期望的输出
// testing官方手册  https://pkg.go.dev/testing@go1.22.3
// 测试运行命令
// go test -run ”        # Run all tests.
// go test -run Foo       # Run top-level tests matching "Foo", such as "TestFooBar".
// go test -run Foo/A=    # For top-level tests matching "Foo", run subtests matching "A=".
// go test -run /A=1      # For all top-level tests, run subtests matching "A=1".
// go test -fuzz FuzzFoo  # Fuzz the target matching "FuzzFoo"
//
// 使用 TestXxx语法进行测试
func TestSpeechDemo(t *testing.T) {
	p1 := &Person{Name: "John", Age: 18}
	SpeechDemo(p1)  // 这里需要自己判断测试是否通过 如果未通过使用 t.Fatalf来格式化输出异常信息(或者函数抛异常也会是失败), 否则使用 t.Logf
	t.Fatal("测试失败") //直接指定这个测试是失败的 这时就会输出所有的控制台结果 包括被测试对象中使用fmt.Print打印的结果
	t.Log("abc ok")

	// 点击函数上方的 run test 这个会输出以下信息
	// go test -timeout 30s -run ^TestSpeechDemo$ tekin.cn/golearn/src/interface/genric_args

	// John正在演讲
	// John正在游泳
	// --- FAIL: TestSpeechDemo (0.00s)
	//
	//	/xxx/golang_learn_mod/src/interface/genric_args/person_test.go:29: 测试失败
	//
	// FAIL
	// FAIL	tekin.cn/golearn/src/interface/genric_args	0.281s
	// FAIL
}

// 使用 ExampleXxx方法进行测试
func ExampleSpeechDemo2() {
	p := &Person{Name: "Alex", Age: 20}
	SpeechDemo2(p)
	// output:Alex正在演讲
	// Alex正在考试
}

func ExampleSpeechDemo3(t *testing.T) {
	// p := &Person{Name: "Alex", Age: 20}
	// SpeechDemo3(p) //这里直接报语法错误 无法编译 因为 参数p缺少方法 Flight
	// output: T (type *Person) does not satisfy interface{Flight(); Speech() string} (missing method Flight)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/609711.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是分库分表?代表性框架有哪些?

在互联网系统开发过程中,所谓的分库分表并不是一个新概念。或者说,对于很多开发人员而言,说起分库分表,大家都或多或少有所了解,也都知道数据量大了就需要进行分库分表。但是究竟如何实现分库分表呢? 要想…

创建Spring Boot项目及配置

目录 一、创建项目所需要的插件 1、安装插件 二、创建项目 三、创建项目所面临的常见问题。 1、IDEA不能识别 2、无效的发行版本 3、确认jar包是否下载成功 一、创建项目所需要的插件 1、安装插件 首先需要在IDEA插件里面搜索Spring,选择Spring Boot Helper…

什么是短信群发上行和下行

短信群发是一种广泛应用于商业和个人通信的技术,通过一次多条的方式,可以快速高效地传递信息。在实际的群发过程中,会涉及到上行和下行的概念。本文将详细介绍什么是短信群发上行和下行,并解释它们的应用。 什么是短信群发上行 群…

Dbeaver连接一段时间不操作后断开的问题

右键数据库连接点击编辑连接点击初始化将连接保持改成60s

BW4HANA混合建模 用ADSO的哪个视图?

写日志的ADSO除了1,2,3表之外。还会有6,7,8view。8view是上了BW4HANA2.0之后激活ADSO就会生成的。如果旧版本没有8,那就RSDG_ADSO_ACTIVATE激活一下。 如果勾了外部HANA视图,那就等于说还有一个HANA view。 首先咱知道ADSO是BW里面用来物理存储&#xf…

做一个属于自己的软件-pyside6快速上手教程

首先环境需要安装python3和pip,软件使用pycharm,安装也都很简单 首先需要安装pyside6,在终端执行: pip install pyside6 然后进入可视化编辑界面 pyside6-designer 进入后创建即可 可以从左侧点击鼠标拉组件进入到中间的工作区&#xff…

BLIP和BLIP2 论文讲解

文章目录 BLIPIntroductionMethod模型架构预训练目标字幕和过滤(Capfilt) BLIP2IntroductionMethod模型结构Q-Former预训练第一阶段Q-Former预训练第二阶段 BLIP 论文: 《BLIP: Bootstrapping Language-Image Pre-training for Unified Visio…

详解BOM编程

华子目录 BOM编程window对象常见的window对象的属性常见的window对象的方法注意 history对象history对象的属性history对象的方法 screen 对象navigator 对象属性方法 location对象属性方法示例 BOM编程 JavaScript本质是在浏览器中运行,所以JavaScript提供了BOM&a…

一文详解FDA邮件认证证书的重要性及其应用

随着全球化和电子商务的飞速发展,跨国贸易和沟通变得越来越频繁。在这个过程中,邮件作为重要的沟通工具,其安全性和可信度成为了各方关注的焦点。FDA(美国食品药品监督管理局)邮件认证证书就是在这一背景下应运而生的一…

1W 3KVDC 隔离 稳压单输出 DC/DC 电源模块——TPV-SAR 系列

TPV-SAR系列产品是专门针对PCB上分布式电源系统中需要与输入电源隔离且输出精度要求较高的电源应用场合而设计。该产品适用于;1)输入电源的电压变化≤5%;2)输入输出之前要求隔离电压≥3000VDC;3)对输出电压…

mac电脑如何安装java

1、检查当前系统的 Java 版本 打开终端,输入以下命令查看当前 Java 版本 /usr/bin/java -version 2、前往 Java 官网下载 Java JDK 打开 Java 官网 (https://www.java.com/zh-CN/download/) 并下载最新版本的 Java JDK。 3、安装 Java JDK 双击下载的 .dmg 文件启动安装程序…

【全开源】Java共享台信息共享系统源码

特色功能 信息整合与共享:该平台提供一站式信息整合服务,将各种类型的信息资源进行汇聚,方便用户快速查找和获取所需资源。多种共享功能:支持信息共享、共享车位、共享会议室、共享电动车等多种共享功能,提高资源利用…

Windows系统本地部署DrawDB数据库设计工具并实现无公网IP远程访问

文章目录 1. Windows本地部署DrawDB2. 安装Cpolar内网穿透3. 实现公网访问DrawDB4. 固定DrawDB公网地址 开发中很多时候都会使用到数据库,所以选择一个好用的数据库设计工具会让工作效率翻倍。在当今数字化时代,数据库管理是许多企业和个人项目的核心。设…

vue-fontawesome-elementui-icon-picker选择icon框架

第一步:安装vue-fontawesome-elementui-icon-picker依赖 npm install vue-fontawesome-elementui-icon-picker --save-dev 第二步:main.js配置 (放在element ui引入之后) import iconPicker from vue-fontawesome-elementui-icon-picker; Vue.use(ico…

Python-VBA函数之旅-setattr函数

目录 一、setattr函数的常见应用场景 二、setattr函数使用注意事项 三、如何用好setattr函数? 1、setattr函数: 1-1、Python: 1-2、VBA: 2、推荐阅读: 个人主页: https://blog.csdn.net/ygb_1024?…

笨方法自学python(六)

上一节中出现了\n,这个作用是换行。\后面带不同字符有不同的作用,我们先简单了解几个, 使用反斜杠 \ (back-slash) 可以将难打印出来的字符放到字符串。针对不同的符号有很多这样的所谓“转义序列(escape sequences)”,我们来练习…

OPC :快速上手

本系列为OPC技术的快速上以及持续研究和技术实战专栏,将不定期更新。 本章节提供OPC系列技术博文的快速导航。 《OPC服务器简介和入门介绍》 《物联网平台如何为OPC服务器创造新生命力》 《OPC服务器开发之WtOPCSvr——开发文档(1)》 《OPC服…

使用flutter开发一个U盘文件管理APP,只解析图片文件

今天教大家用flutter撸一个U盘文件管理APP,需求是这样的: 当我在Android设备上插入U盘后,我能在APP中打开U盘的文件目录,并且能进入对应目录的下一级目录,如果下级目录下有图片文件,我就对这个图片文件进行解析,并展示出来。 需求了解后,先上个效果图: 效果图看完后,…

海外媒体发稿:7个出口贸易媒体发稿推广必备技巧-华媒舍

在如今全球化的经济环境中,出口贸易在各个国家的经济中占据了重要地位。作为出口贸易从业者,我们都明白推广产品和品牌对于成功开拓国际市场至关重要。而在推广方面,媒体发稿则是一种常见而有效的方式。本文将分享7个出口贸易媒体发稿推广的必…

Spark云计算平台Databricks使用,创建workspace和Compute计算集群(Spark集群)

Databricks,是属于 Spark 的商业化公司,由美国加州大学伯克利 AMP 实验室的 Spark 大数据处理系统多位创始人联合创立。Databricks 致力于提供基于 Spark 的云服务,可用于数据集成,数据管道等任务。 1 创建workspace 点击创建wor…
最新文章