美文网首页
go泛型入门

go泛型入门

作者: 护念 | 来源:发表于2023-07-12 21:26 被阅读0次

什么是泛型,简单点说就是,用同一个函数,处理不同的数据类型。

看下面的例子,会有深入的感受

1.用两个不同类型的函数,处理不同的类型

  • 初始化项目
mkdir generics
cd generics
go mod init example/generics # 初始化模块
  • 完善main.go文件
    创建touch main.go文件
// mian.go
package main

import "fmt"

func main() {
     // 初始化整数映射
    ints := map[string]int64{
        "first":  34,
        "second": 12,
    }

    // 初始化浮点数映射
    floats := map[string]float64{
        "first":  35.98,
        "second": 26.99,
    }

    fmt.Printf("Non-Generic Sums: %v and %v\n",
        SumInts(ints),
        SumFloats(floats))
}

// int64 求和
func SumInts(m map[string]int64) int64 {
    var s int64
    for _, v := range m {
        s += v
    }
    return s
}

// float64求和
func SumFloats(m map[string]float64) float64 {
    var s float64
    for _, v := range m {
        s += v
    }
    return s
}
  • 运行,go run .
dongmingyan@pro ⮀ ~/go_playground/generics ⮀ go run .
Non-Generic Sums: 46 and 62.97

2.引入泛型

在上面我们用了两个不同的函数分别处理int和float类型,实在有点麻烦;这里我们用一个函数实现

// main.go
package main

import "fmt"

func main() {
     // 初始化整数映射
    ints := map[string]int64{
        "first":  34,
        "second": 12,
    }

    // 初始化浮点数映射
    floats := map[string]float64{
        "first":  35.98,
        "second": 26.99,
    }

    fmt.Printf("Non-Generic Sums: %v and %v\n",
        SumIntsOrFloats[string, int64](ints), // 使用时候也多传下类型,如果可以类型推断出来可以省略
        SumIntsOrFloats[string, float64](floats))

        // 和上写法等效
        fmt.Printf("Non-Generic Sums: %v and %v\n",
        SumIntsOrFloats(ints),
        SumIntsOrFloats(floats))
}
// 求和浮点数或整数
// [] 里申明类型
// comparable代表一种可以比较的类型
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
    var sum V

    for _, v := range m {
        sum += v
    }
    return sum
}

运行

dongmingyan@pro ⮀ ~/go_playground/generics ⮀ go run .
Non-Generic Sums: 46 and 62.97
Non-Generic Sums: 46 and 62.97

小结:方式就是在函数开头加上[],设定好支持哪些类型

3.优化-类型约束

上面的写法已经实现了替代两个函数,但是并不简洁,如果有许多个地方都需要用到这种数据类型,我们并没有办法复用;我们可以把这里的类型抽取出来

// main.go
package main

import "fmt"

func main() {
     // 初始化整数映射
    ints := map[string]int64{
        "first":  34,
        "second": 12,
    }

    // 初始化浮点数映射
    floats := map[string]float64{
        "first":  35.98,
        "second": 26.99,
    }

    fmt.Printf("Non-Generic Sums: %v and %v\n",
        SumIntsOrFloats[string, int64](ints), // 使用时候也多传下类型,如果可以类型推断出来可以省略
        SumIntsOrFloats[string, float64](floats))

        // 和上写法等效
        fmt.Printf("Non-Generic Sums: %v and %v\n",
        SumIntsOrFloats(ints),
        SumIntsOrFloats(floats))
}

// 这里申明一种Number类型 可以同时代表int64和float64
type Number interface{
    int64 | float64 // 注意这里是单竖线
}

// 求和浮点数或整数
// [] 里申明类型
// compareable代表一种可以比较的类型 Number复用其中
func SumIntsOrFloats[K comparable, V Number](m map[K]V) V {
    var sum V

    for _, v := range m {
        sum += v
    }
    return sum
}

相关文章

  • go 泛型

    go 泛型 1. 类型参数(Type parameters) Go语言的泛型(Generic)叫做类型参数。泛型可...

  • 夯实 Java 基础1 - 泛型的使用与原理

    Java 泛型为我们写安全易读的通用程序提供了便利,Go 也将在 2.0 引入泛型。下面首先介绍 Java 泛型的...

  • Java 泛型

    本文只是做为泛型的入门和基础的泛型的了解。 什么是泛型?泛型(generices)是JDK5引入的新特性,这个特性...

  • 详解Java泛型之4——一个例子理解泛型带来的好处

    前面我介绍了关于泛型、通配符以及泛型擦除的相关知识点,大家可以参考以下文章: 详解Java泛型之1——入门泛型必懂...

  • 详解Java泛型之3——十分钟理解泛型擦除

    前面我们介绍了泛型以及通配符的基础概念,可以参考文章: 详解Java泛型之1——入门泛型必懂的知识点[https:...

  • Golang学习笔记---“泛型”的实现

    Golang学习笔记---“泛型”的实现 大家都知道,go语言中是没有泛型的,但是我们可以通过空接口的方式来实现泛...

  • Go语言 泛型

    本篇文章转载自 在go中使用"泛型" 在进入泛型的话题之前, 首先实现对int 数组切片的冒泡排序: 如你所见, ...

  • go泛型体验

    背景 有了泛型可以做到复用,比如sort,filter,map,reduce等常用方法,这里举个ch的例子我们写g...

  • TypeScript基础入门 - 泛型 - 泛型类

    转载 TypeScript基础入门 - 泛型 - 泛型类 项目实践仓库 为了保证后面的学习演示需要安装下ts-no...

  • Go 泛型初体验

    在 Go1.17 中,千呼万唤的泛型终于出来了,但又没有完全出来。在 Go1.17 的发布文档中,并没有提到泛型,...

网友评论

      本文标题:go泛型入门

      本文链接:https://www.haomeiwen.com/subject/uqipudtx.html