go1.18新特性

前言

最近突然发现golang更新版本1.18了, 于是迫不及待的来看看这个版本加了些什么新特性. 没准就有之前困扰很久的问题, 在新版本被官方解决了呢.

先简单概述一下都有些什么变化, 后面再细说:

  1. 增加泛型的支持
  2. 系统库方法增加
  3. 修复 bug

另外, 像"系统内核更新"这种, 我们在实际开发中根本就无需关心的内容, 我就没有列出, 完整更新内容到官网去看吧. 1.18版本的官方说明链接: https://golang.google.cn/doc/go1.18

其实, 整个看下来, 最大的变动就是增加了泛型的支持. 可以说是千呼万唤始出来了. 主要就看看这个泛型呗. 有需要的快升级了, 官方的说法是, 完全向后兼容.

泛型

还记得在这之前, 要写一个返回二者最小值的min函数, 我们是怎么做的呢?

/*
方案一
每个类型都添加一个方法
*/
func minInt(a, b int) int {
    if a < b {
        return a
    } else {
        return b
    }
}

func minInt64(a, b int64) int64 {
    if a < b {
        return a
    } else {
        return b
    }
}

// ... 其他类型的方法

/*
方案二
通过 interface 接收参数并返回
*/
func min(a, b interface{}) interface{} {
    changeToFloat64 := func(v interface{}) float64 {
        if vInt64, ok := v.(int64); ok {
            return float64(vInt64)
        } else if vInt32, ok := v.(int32); ok {
            return float64(vInt32)
        } else if vInt, ok := v.(int); ok {
            return float64(vInt)
        } else if vFloat32, ok := v.(float32); ok {
            return float64(vFloat32)
        } else if vFloat64, ok := v.(float64); ok {
            return vFloat64
        } else { // 其他类型判断
            return 0
        }
    }
    floatA := changeToFloat64(a)
    floatB := changeToFloat64(b)
    if floatA < floatB {
        return floatA
    } else {
        return floatB
    }
}

而这两种实现方式都存在其不足.

方案一(多个方法的实现), 其问题在于将相同的逻辑在所有方法中都重复实现了一遍, 同时每个类型的函数名都不一样, 也增加了函数调用的难度.

方案二(通过判断类型), 这样确实将大小比较的逻辑放到一起来, 但返回值也变成interface了, 函数的调用方接到返回时还需要进行一次转型.

而有了泛型之后, 函数就可以这样写了:

func minNew[T int|float32](a, b T) T {
    if a < b {
        return a
    } else {
        return b
    }
}

是不是简洁很多了. 在线运行

相信你也注意到了, 上面函数中有这样一段内容[T int|float32]. 这段是对T这个泛型的约束, 指定这个泛型具有哪些特性的.如果在上面的约束中加上interface那就回报错了, 因为interface是无法进行大小比较的.

泛型及其约束的使用方式如下:

// any 同 interface{}
type anyDemo[T any] []T
// comparable 用来标识所有可以使用 ==/!= 进行比较的类型
type anyDemo[T comparable] []T
// 限制泛型 T 为 int|int32|float32 其中一个
type anyDemo[T int|int32|float32] []T
/*
约束前添加 "~"符合, 意为底层类型
例如定义类型: type myInt int
myInt 类型变量底层类型为 int, 但仍然是两个不同的类型
若泛型约束为 int, 那么就不能接受 myInt 类型的变量
而泛型约束为 ~int, 就可以接受 myInt 类型的变量
 */
type anyDemo[T ~int|int32] []T

// 泛型类型定义方法
func (m *anyDemo[T]) Push(v T) *anyDemo[T] {
    *m = append(*m, v)
    return m
}
// 方法中使用
func funcDemo[T any](a, b T) T{}
// 结构体中使用泛型
type structDemo[T1, T2 any] struct{
  t1 T1
  arr []T2
}

// 泛型约束也可以通过接口进行定义, 以方便使用
// 定义不同类型的集合
type inter1 interface {
  ~int | ~int8 | ~int16 | ~int32 | ~int64 |
  ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
  ~float32 | ~float64 |
  ~string
}

同时也增加了支持泛型的系统库:


完了, 就这么点玩意


原文地址 https://hujingnb.com/archives/755

转载请保留原文连接: go1.18新特性 | 烟草的香味

订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请发表评论。x