Go泛型简介

go,简介 · 浏览次数 : 60

小编点评

## Go 语言泛型 Go 语言的泛型是通过在函数或类型定义中使用类型参数来实现的。类型参数可以被看作是一个特殊的类型,它可以在函数或类型定义中的任何位置使用。 **关键点:** * 泛型是在编译时实现的,这意味着所有的类型检查是在编译时进行的,而不是在运行时。 * 泛型提供了代码复用和类型安全的优点。 * 泛型也可能导致编译时间增加和生成的二进制文件变大。 **示例:** 1. 泛型函数接受一个类型参数T,并返回T类型的切片中的第一个元素。 2. 泛型类型定义了一个可以存储任何类型元素的栈。 3. 自定义约束定义了一个函数,该函数接受一个实现了Stringer接口的类型参数。 **使用泛型的好处:** * 代码更易读,因为不需要为每种数据类型编写重复的代码。 * 泛型提供代码复用的机会。 * 泛型可以确保类型安全。 **注意:** * 泛型可能会导致编译时间增加。 * 泛型可能会导致生成的二进制文件变大。

正文

Go语言的泛型是在Go 1.18版本中引入的一个新特性,它允许开发者编写可以处理不同数据类型的代码,而无需为每种数据类型都编写重复的代码。以下是关于Go语言泛型的一些关键点:

  1. 泛型是通过在函数或类型定义中使用类型参数来实现的。类型参数可以被看作是一个特殊的类型,它可以在函数或类型定义中的任何位置使用。
  2. 在函数或类型定义中,类型参数的列表是在名称后面的方括号中给出的。例如,在函数定义 func PrintSlice[T any](s []T) {...} 中,T 是一个类型参数,any 是它的约束。
  3. 约束定义了类型参数可以接受的类型范围。例如,any 约束允许类型参数接受任何类型,包括内置类型、接口类型、结构体类型等。
  4. 你可以定义自己的约束,通过定义一个接口类型,然后在类型参数列表中使用它。类型参数必须满足这个接口的所有方法。
  5. Go语言的泛型是在编译时实现的,这意味着所有的类型检查都是在编译时进行的,而不是在运行时。
  6. Go语言的泛型提供了代码复用和类型安全的优点,但是它也可能导致编译时间增加和生成的二进制文件变大。

以下是一些使用Go语言泛型的示例:

1. 泛型函数

接受一个类型参数T,并返回T类型的切片中的第一个元素。

package main

import "fmt"

func First[T any](s []T) (T, bool) {
    if len(s) == 0 {
        var zero T
        return zero, false
    }
    return s[0], true
}

func main() {
    fmt.Println(First[int]([]int{1, 2, 3}))
    fmt.Println(First[string]([]string{"Hello", "World"}))
}

2. 泛型类型

定义了一个可以存储任何类型元素的栈。

package main

import "fmt"

type Stack[T any] []T

func (s *Stack[T]) Push(v T) {
    *s = append(*s, v)
}

func (s *Stack[T]) Pop() (T, bool) {
    if len(*s) == 0 {
        var zero T
        return zero, false
    }
    index := len(*s) - 1
    element := (*s)[index]
    *s = (*s)[:index]
    return element, true
}

func main() {
    s := Stack[int]{}
    s.Push(1)
    s.Push(2)
    s.Push(3)
    fmt.Println(s.Pop())
    fmt.Println(s.Pop())
    fmt.Println(s.Pop())
}

3. 自定义约束

定义了一个函数,该函数接受一个实现了Stringer接口的类型参数。

package main

import (
    "fmt"
    "strconv"
)

type Stringer interface {
    String() string
}

func Print[T Stringer](s T) {
    fmt.Println(s.String())
}

type MyInt int

func (m MyInt) String() string {
    return strconv.Itoa(int(m))
}

func main() {
    Print[MyInt](MyInt(10))
}

在这个例子中,Print函数接受一个实现了Stringer接口的类型参数。MyInt类型实现了Stringer接口,所以我们可以将MyInt类型的值传递给Print函数。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
author: mengbin
blog: mengbin
github: mengbin92
cnblogs: 恋水无意


与Go泛型简介相似的内容:

Go泛型简介

Go语言的泛型是在Go 1.18版本中引入的一个新特性,它允许开发者编写可以处理不同数据类型的代码,而无需为每种数据类型都编写重复的代码。以下是关于Go语言泛型的一些关键点: 1. 泛型是通过在函数或类型定义中使用类型参数来实现的。类型参数可以被看作是一个特殊的类型,它可以在函数或类型定义中的任何位

Go泛型解密:从基础到实战的全方位解析

本篇文章深入探讨了Go语言的泛型特性,从其基础概念到高级用法,并通过实战示例展示了其在实际项目中的应用。 关注【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资

golang 泛型的格式写法

Go语言中的泛型(Generics)是在 Go 1.18 版本中引入的一个重要特性,它允许你编写可重用的代码,而不需要为每种数据类型重复编写相同的逻辑。 泛型通过参数化类型(type parameters)来实现,使得函数、方法、接口和结构体可以与多种类型一起工作。 下面详细介绍Go语言中泛型的基本

go多版本管理

在日常开发工作过程中,很多时候我们都需要在自己的机器上安装多个go版本,像是go1.16引入的embed,go1.18引入了泛型;又或是自己本地使用的是最新版,但公司的项目中使用的go1.14、go1.13甚至是更早的版本。 那么有没有既不影响我们自己的本地环境,又能兼顾历史项目的办法呢?答案当然是

Go微服务开发指南

在这篇深入探讨Go语言在微服务架构中的应用的文章中,我们介绍了选择Go构建微服务的优势、详细分析了主要的Go微服务框架,并探讨了服务发现与注册和API网关的实现及应用。 关注TechLead,复旦博士,分享云服务领域全维度开发技术。拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,复旦机器

Go 使用原始套接字捕获网卡流量

Go 使用原始套接字捕获网卡流量 Go 捕获网卡流量使用最多的库为 github.com/google/gopacket,需要依赖 libpcap 导致必须开启 CGO 才能够进行编译。 为了减少对环境的依赖可以使用原始套接字捕获网卡流量,然后使用 gopacket 的协议解析功能,这样就省去了解析

Go 如何对多个网络命令空间中的端口进行监听

Go 如何对多个网络命令空间中的端口进行监听 需求为 对多个命名空间内的端口进行监听和代理。 刚开始对 netns 的理解不够深刻,以为必须存在一个新的线程然后调用 setns(2) 切换过去,如果有新的 netns 那么需要再新建一个线程切换过去使用,这样带来的问题就是线程数量和 netns 的数

【建议收藏】Go语言关键知识点总结

容器 数组和切片 在Go语言中,数组和切片是两个基本的数据结构,用于存储和操作一组元素。它们有一些相似之处,但也有许多不同之处。下面我们详细介绍数组和切片的特点、用法以及它们之间的区别。 数组 数组是固定长度的序列,存储相同类型的元素。数组的长度在定义时就固定下来,不能改变。 package mai

如何基于R包做GO分析?实现秒出图

GO分析 基因本体论(Gene Ontology, GO)是一个用于描述基因和基因产品属性的标准术语体系。它提供了一个有组织的方式来表示基因在生物体内的各种角色。基因本体论通常从三个层面对基因进行描述:细胞成分(Cellular Component,CC)、生物学过程(Biological Proc

Go变量作用域精讲及代码实战

关注作者,复旦AI博士,分享AI领域与云服务领域全维度开发技术。拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕博,复旦机器人智能实验室成员,国家级大学生赛事评审专家,发表多篇SCI核心期刊学术论文,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。 精讲