2023年9月26日 Go生态洞察:深入解析类型参数


🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁

🦄 博客首页——🐅🐾猫头虎的博客🎐
🐳 《面试题大全专栏》 🦕 文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺
🌊 《IDEA开发秘籍专栏》 🐾 学会IDEA常用操作,工作效率翻倍~💐
🌊 《100天精通Golang(基础入门篇)》 🐅 学会Golang语言,畅玩云原生,走遍大小厂~💐

🐅🐾猫头虎建议Go程序员必备技术栈一览表📖:

☁️🐳 Go语言开发者必备技术栈☸️:
🐹 GoLang | 🌿 Git | 🐳 Docker | ☸️ Kubernetes | 🔧 CI/CD | ✅ Testing | 💾 SQL/NoSQL | 📡 gRPC | ☁️ Cloud | 📊 Prometheus | 📚 ELK Stack


🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🐅🐾🍁🐥


在这里插入图片描述

文章目录

    • 🐅🐾猫头虎建议Go程序员必备技术栈一览表📖:
  • 2023年9月26日 Go生态洞察:深入解析类型参数
    • 🐾 正文内容
      • 🐈 `slices`包函数签名
      • 🐈 简单的克隆实现
      • 🐈 灵活的克隆实现
      • 🐈 底层类型约束
      • 🐈 类型推断
      • 🐈 类型参数的解构
    • 🐾 总结
  • 原创声明

  • 原创作者: 猫头虎

  • 作者wx: Libin9iOak

  • 作者公众号: 猫头虎技术团队

在这里插入图片描述

2023年9月26日 Go生态洞察:深入解析类型参数

🐾 摘要
大家好,我是猫头虎,今天我们要探讨的是Go语言中类型参数的构造和使用。通过深入分析slices.Clone函数,我们将理解类型参数在Go泛型中的作用和重要性。这不仅是一个技术深度话题,而且对于深入理解Go语言的泛型系统至关重要。

🐾 引言
在Go 1.18的引入泛型之后,类型参数成为了Go语言的一个新亮点。它们提供了编写更加灵活和可复用代码的能力。本文将通过Clone函数的例子,展示如何有效地使用类型参数来增强代码的通用性和灵活性。


🐾 正文内容

🐈 slices包函数签名

Clone函数非常简单:它可以复制任何类型的切片。

func Clone[S ~[]E, E any](s S) S {return append(s[:0:0], s...)
}

这个函数之所以有效,是因为对零容量的切片进行追加操作会分配一个新的底层数组。函数体实际上比函数签名更短,这部分是因为体本身简短,但也因为签名较长。接下来,我们将解释为什么签名是这样写的。

🐈 简单的克隆实现

我们首先编写一个简单的通用Clone函数。这并不是slices包中的那一个。我们希望接受任何元素类型的切片,并返回一个新切片。

func Clone1[E any](s []E) []E {// body omitted
}

泛型函数Clone1有一个类型参数E。它接受一个类型为E的切片参数s,并返回同类型的切片。这个签名对熟悉Go中泛型的人来说很直接。

然而,这里有一个问题。在Go中,命名的切片类型不常见,但人们确实会使用它们。

// MySlice 是一个具有特殊String方法的字符串切片。
type MySlice []string// String 返回MySlice值的可打印版本。
func (s MySlice) String() string {return strings.Join(s, "+")
}

假设我们想要复制一个MySlice,然后获取其排序后的可打印版本。

func PrintSorted(ms MySlice) string {c := Clone1(ms)slices.Sort(c)return c.String() // 编译失败
}

不幸的是,这不起作用。编译器报告错误:

c.String undefined (type []string has no field or method String)

🐈 灵活的克隆实现

为了解决这个问题,我们必须编写一个版本的Clone,它返回与其参数相同的类型。如果我们做到了这一点,那么当我们用MySlice类型的值调用Clone时,它将返回MySlice类型的结果。

我们知道它应该是这样的:

func Clone2[S ?](s S) S // 无效

这个Clone2函数返回与其参数相同类型的值。

🐈 底层类型约束

如错误消息所示,答案是添加一个~

func Clone5[S ~[]E, E any](s S) S

再次强调,用[S []E, E any]这样的类型参数和约束表示,意味着S的类型参数可以是任何未命名的切片类型,但

不能是定义为切片字面量的命名类型。用[S ~[]E, E any],加上~,意味着S的类型参数可以是任何底层类型为切片类型的类型。

🐈 类型推断

现在我们已经解释了slices.Clone的签名,让我们看看如何通过类型推断简化对slices.Clone的使用。

func Clone[S ~[]E, E any](s S) S

调用slices.Clone时,将传递一个切片给参数s。类型推断将允许编译器推断出类型参数S是传递给Clone的切片的类型。然后,类型推断足够强大,可以看出E的类型参数是传递给S的类型参数的元素类型。

🐈 类型参数的解构

我们在这里使用的一般技术,即使用另一个类型参数E定义一个类型参数S,是一种在泛型函数签名中解构类型的方法。通过解构类型,我们可以命名并约束类型的所有方面。

例如,这是maps.Clone的签名:

func Clone[M ~map[K]V, K comparable, V any](m M) M

就像slices.Clone一样,我们使用一个类型参数来表示参数m的类型,然后使用另外两个类型参数KV来解构该类型。

maps.Clone中,我们将K约束为可比较的,因为这是映射键类型所必需的。我们可以根据喜好约束组成类型。

func WithStrings[S ~[]E, E interface { String() string }](s S) (S, []string)

这表示WithStrings的参数必须是一个切片类型,其元素类型具有String方法。

由于所有Go类型都可以从组成类型构建,我们总是可以使用类型参数来解构这些类型,并根据我们的喜好对它们进行约束。


🐾 总结

总的来说,类型参数在Go泛型中扮演着至关重要的角色。通过精心设计的函数签名和有效利用类型推断,我们可以编写更灵活、更通用的代码。希望这篇文章能帮助你更好地理解Go中的泛型。这篇文章由猫头虎的Go生态洞察专栏收录,更多详情请点击这里。

关键点描述
类型参数使用使用类型参数构建灵活通用的函数
slices.Clone分析分析Clone函数的类型参数和其用法
底层类型约束理解底层类型的约束和它们的应用
类型推断探索类型推断在泛型编程中的作用

下一篇预告: 下一篇文章将深入探讨Go语言中的类型推断——《关于类型推断的一切——还有更多》。我们将继续深入泛型编程的精髓,探索类型推断如何简化我们的编码过程。敬请期待!�

在这里插入图片描述

原创声明

======= ·

  • 原创作者: 猫头虎

  • 作者wx: Libin9iOak
    在这里插入图片描述

  • 作者公众号: 猫头虎技术团队

在这里插入图片描述

学习复习Go生态

本文为原创文章,版权归作者所有。未经许可,禁止转载、复制或引用。

作者保证信息真实可靠,但不对准确性和完整性承担责任

未经许可,禁止商业用途。

如有疑问或建议,请联系作者。

感谢您的支持与尊重。

点击下方名片,加入IT技术核心学习团队。一起探索科技的未来,洞察Go生态,共同成长。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023第十二届“认证杯”D题:CMOS黄昏系数|数学中国数学建模国际赛(小美赛)| 建模秘籍文章代码思路大全

铛铛!小秘籍来咯! 小秘籍希望大家都能轻松建模呀,数维杯也会持续给大家放送思路滴~ 抓紧小秘籍,我们出发吧~ 来看看认证杯(D题)! 完整内容可以在文章末尾领取! 问题重述&#x…

【小红书运营指南1】赛道选择 + 账号运营全周期

小红书运营指南1 写在最前面11.23标签一级标签二级标签 网络资源整理1. 赛道选择近2年小红书女性人群画像 2. 基础认知阶段3. 账号启动阶段4. 选题规划阶段5. 爆款打造阶段6. 涨粉变现阶段涨粉变现阶段粉丝发展阶段 写在最前面 最近做的一个项目调研,调研和实际有一…

Linux基本指令(超详版)

Linux基本指令(超详版) 1. ls指令2.pwd指令3. cd 指令4.touch指令5mkdir指令6.rmdir指令&&rm指令7.man指令7.cp指令8.mv指令9.echo指令10.cat指令11.more指令12.less指令13.head指令14.tail指令15.date指令16.find指令17.grep指令zip(打包压缩) …

JVM类加载器ClassLoader的源码分析

1、ClassLoader与现有类加载器的关系 ClassLoader与现有类加载器的关系: ClassLoader是一个抽象类。如果我们给定了一个类的二进制名称,类加载器应尝试去定位或生成构成定义类的数据。一种典型的策略是将给定的二进制名称转换为文件名,然后去…

C语言--实现一个函数把一个整数转为它对应的十六进制的字符串

一.题目描述 实现一个函数把一个整数转为它对应的十六进制的字符串。 比如:输入数字1234 输出:4D2 二.思路分析 用一个sprintf函数可以解决问题,输出相对应的字符串 要注意的问题就是:函数结束后要继续使用的内存(比如…

Carla自动驾驶仿真六:pygame多个车辆摄像头画面拼接

此文章主要介绍carla前后左右摄像头画面拼接到pygame上 文章目录 前言一、要点分析二、完整代码三、拼接效果四、总结 前言 1、使用carla做仿真测试或者开发时,如果能够将车辆周边的画面拼接并渲染,可以直观地查看周围地环境,便于调试。本文…

基于ssm的学生公寓管理中心系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本学生公寓管理中心系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据…

[报错]记录IDEA远程开发报错:java: Cannot run program.....

报错内容 IDEA在进行远程开发的时候报错,内容如下: java: Cannot run program "/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java" (in directory "/home/jim/.cache/JetBrains/RemoteDev-IU/_home_jim_DevCodes_Github_zfile/compile-…

redis主从复制【面试必看】

在分布式系统中,希望使用多个服务器来部署redis,存在以下几种redis的部署方式 主从模式主从哨兵集群模式 主从模式 在若干个redis节点中,有的是主节点,有的是从节点 假设有三个物理服务器(称为是三个节点&#xff…

(JSP)EL——优化登录界面,获取对象,获取数据

EL优化登录界面 <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <% String path request.getContextPath(); String basePath request.getScheme()"://"request.getServerName()":"reques…

生产工序(oj题)

很有趣的一道题 关键在于固定工序的整合 看样例是固定工序中间是不能插入其他工序的&#xff08;也不讲清楚&#xff09;&#xff0c;如果可以的话&#xff0c;只能说可能会更麻烦 注意固定工序是按照固定工序中的第一个工序进行排序的 整合完之后&#xff0c;就是递归列出…

Java中的IO流①——IO流的体系、字节流、try...catch异常处理

概述 IO流的分类 IO流的体系 这四个类都是抽象类&#xff0c;所以需要实现类对象才能使用---> 字节流 FileInputStream--> 书写细节 代码示范 此时文件a.txt内容为abcde 使用char强转和read方法调用五次read方法--> public static void main(String[] args) throws IO…

初出茅庐的小李博客之TobudOS移植到EVB_AIoT开发板

本博客参考教程&#xff1a; https://atomgit.com/OpenAtomFoundation/TobudOS/blob/master/doc/TobudOS_EVB_AIoT_STM32_Guide.md 介绍一下EVB_AIoT开发板 这个开发板是由TobudOS开源社区联合意法半导体、南京厚德物联网设计的一款高性能IoT开发平台&#xff0c;主控芯片是S…

SystemVerilog学习(0)——目录与传送门

一、验证导论 SystemVerilog学习&#xff08;1&#xff09;——验证导论-CSDN博客文章浏览阅读403次。SystemVerilog自学&#xff0c;验证系统概述&#xff0c;什么是SVhttps://blog.csdn.net/apple_53311083/article/details/133953016 二、数据类型 SystemVerilog学习&…

@FunctionalInterface、Lambda表达式和方法引用

知识不回顾是会被遗忘的&#xff01; 网上看了一些相关文章&#xff0c;这里记录一下&#xff0c;仅供参考 Java语言从JDK1.8开始引入了函数式编程。 函数式编程的核心特点是&#xff0c;函数作为一段功能代码&#xff0c;可以像变量一样进行引用和传递&#xff0c;以便在有需…

stm32 使用18B20 测试温度

用18b20 测试温度是非常常用的&#xff0c;不过18B20的调试不是这么容易的&#xff0c;有些内容网上很多的&#xff0c;不再重复说了&#xff0c;我先把波形说一下&#xff0c;再说程序部分&#xff1a; 整个都温度数据的顺序是&#xff1a; 1.700uS的低电平复位并测试18B20的…

mfc110u.dll丢失的解决方法,mfc110u.dll丢失原因是什么?

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“mfc110u.dll文件丢失”。那么&#xff0c;mfc110u.dll是什么&#xff1f;为什么会出现丢失的情况呢&#xff1f;本文将为您详细介绍mfc110u.dll文件的含义、丢失原因以及解决方法。 首先&…

MyBatis进阶之结果集映射注解版

文章目录 注解实现结果集映射注解实现关系映射常用功能注解汇总 注解实现结果集映射 注意 配置结果集映射&#xff0c;只用看 SQL 执行结果&#xff0c;不看 SQL 语句&#xff01; 注意 由于注解在映射结果集上没有实现 <resultMap> 的 100% 功能&#xff0c;因此&#x…

【车载开发系列】Visio工具使用小技巧

【车载开发系列】Visio工具使用小技巧 【车载开发系列】Visio工具使用小技巧 【车载开发系列】Visio工具使用小技巧一. Word中编辑Visio技巧二. Word中插入visio图形的问题三. 总结 一. Word中编辑Visio技巧 本节主要介绍了Microsoft Word中编辑Visio图形的具体方法。 在 Word…

单臂路由与三层交换机

单臂路由 划分VLAN后同一VLAN的计算机属于同一个广播域&#xff0c;同一VLAN的计算机之间的通信是不成问题的。然而&#xff0c;处于不同VLAN的计算机即使是在同一交换机上&#xff0c;它们之间的通信也必须使用路由器。 图&#xff08;a&#xff09;是一种实现VLAN间路由的方…