• go泛型使用方法


    golang泛型使用方法

    1. 泛型是什么

    • 泛型生命周期只在编译期,旨在为程序员生成代码,减少重复代码的编写

    • 在比较两个数的大小时,没有泛型的时候,仅仅只是传入类型不一样,我们就要再写一份一模一样的函数,如果有了泛型就可以减少这类代码

      // int
      func GetMaxNumInt(a, b int) int {
      if a > b {
      return a
      }

      return b
      
      • 1

      }

      // int8
      func GetMaxNumInt8(a, b int8) int8 {
      if a > b {
      return a
      }

      return b
      
      • 1

      }

    2. 泛型的简单使用

    2.1. 泛型示例

    • 需要go版本大于等于1.18

    • 我们先改造一下上面的示例,只需要在函数后用中括号声明T可能出现的类型,中间用符号"|" 分隔

      // 使用泛型
      func GetMaxNum[T int | int8](a, b T) T {
      if a > b {
      return a
      }

      return b
      
      • 1

      }

    2.2. 自定义泛型类型

    • 如果类型太多了怎么办呢?这时候我们就可以自定义泛型类型

      // 像声明接口一样声明
      type MyInt interface {
      int | int8 | int16 | int32 | int64
      }

      // T的类型为声明的MyInt
      func GetMaxNum[T MyInt](a, b T) T {
      if a > b {
      return a
      }

      return b
      
      • 1

      }

    2.3. 调用带泛型的函数

    • 如何调用这个带有泛型的函数呢?

      var a int = 10
      var b int = 20

      // 方法1,正常调用,编译器会自动推断出传入类型是int
      GetMaxNum(a, b)

      // 方法2,显式告诉函数传入的类型是int
      GetMaxNum[int](a, b)

    3. 自定义泛型类型的语法

    在2.2小节中我们可以看到一个泛型的简单自定义类型,本节将会详细描述泛型自定义类型的语法

    3.1. 内置的泛型类型any和comparable

    • any: 表示go里面所有的内置基本类型,等价于interface{}
      在这里插入图片描述
    • comparable: 表示go里面所有内置的可比较类型:int、uint、float、bool、struct、指针等一切可以比较的类型
      在这里插入图片描述

    3.2. 声明一个自定义类型

    • 跟声明接口一样,使用type x interface{} 关键字来声明,不过里面的成员不再是方法,而是类型,类型之间用符号 "|" 隔开

      type MyInt interface {
      int | int8 | int16 | int32 | int64
      }

    • 成员类型支持go中所有的基本类型

      type MyT interface {
      int | float32 | bool | chan int | map[int]int | [10]int | []int | struct{} | *http.Client
      }

    3.3. 泛型中的"~"符号是什么

    • 符号"~"都是与类型一起出现的,用来表示支持该类型的衍生类型

      // int8的衍生类型
      type int8A int8
      type int8B = int8

      // 不仅支持int8, 还支持int8的衍生类型int8A和int8B
      type MyInt interface {
      ~int8
      }

    4. 泛型的进阶使用

    4.1. 泛型与结构体

    • 创建一个带有泛型的结构体User,提供两个获取agename的方法

    • 注意:只有在结构体上声明了泛型,结构体方法中才可以使用泛型

      type AgeT interface {
      int8 | int16
      }

      type NameE interface {
      string
      }

      type User[T AgeT, E NameE] struct {
      age T
      name E
      }

      // 获取age
      func (u *User[T, E]) GetAge() T {
      return u.age
      }

      // 获取name
      func (u *User[T, E]) GetName() E {
      return u.name
      }

    • 我们可以通过声明结构体对象时,声明泛型的类型来使用带有泛型的结构体

      // 声明要使用的泛型的类型
      var u User[int8, string]

      // 赋值
      u.age = 18
      u.name = “weiwei”

      // 调用方法
      age := u.GetAge()
      name := u.GetName()

      // 输出结果 18 weiwei
      fmt.Println(age, name)

    5. 泛型的限制或缺陷

    5.1 无法直接和switch配合使用

    • 将泛型和switch配合使用时,无法通过编译

      func GetT any T {
      var t T

      switch T {
      case int:
      	t = 18
      }
      
      return t
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      }

    • 只能先将泛型赋值给interface才可以和switch配合使用

      func GetT any T {
      var t T

      var ti interface{} = &t
      switch v := ti.(type) {
      case *int:
      	*v = 18
      }
      
      return t
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      }

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    TS类型: never 和 unknown
    基于Go语言Iris+Xorm搭建的Web项目框架
    【JS】原生js实现矩形框的绘制/拖动/缩放
    gitLab server version 13.12.1 is not supported
    算法练习15——加油站
    c语言入门---动态内存的分配
    【算法题】合法分组的最少组数
    Springboot 集成 WebSocket
    Lifted ElGamal 门限加密算法
    解决一次Cannot read properties of null (reading ‘length‘)的问题:
  • 原文地址:https://blog.csdn.net/m0_67401499/article/details/126083374