go 1.18新特性(泛性 模糊测试 WorkSpace)

2023-09-15 21:18:19

泛型

interface的功能扩展

在1.18之前,官方对interface的定义是方法的集合,可以存储实现该方法的任意类型。1.18对interface的定义改为类型集合。接口类型的变量可以存储这个接口类型集合的任意一种类型的实例值。

下面是通过接口定义的一个类型集:

type MyNum interface {
	int32 | int64 | float32 | float64 
}

我们在定义类型集的时候,可以在具体类型前加上符号**~** ,表示该类型以及它的别名类型都是该类型集的。

泛型使用

如下是泛型的使用:

func Sum[T MyNum](nums []T) (rnt T) {

	for _, num := range nums {
		rnt += num
	}
	return
}
  • 方法名后面**[]** 中的内容称为泛型参数列表。
  • T 是泛型参数名,自定义的。
  • MyNum 是约束类型,可以是接口定义的一个类型集合。

还有一些变式的用法,如下:

func Sum[T int64 | float32](nums []T) (rnt T) 

func Sum[T interface{}](nums []T) (rnt T) // interface 表示任意类型

除了方法可以使用泛性,struct也可以使用泛型:

type Queue[T MyNum] struct {
	elements []T
}

模糊测试

模糊测试可以先程序或函数输入大量的无效数据,以检测个别输入带来的意外行为,以此来定位错误。 这种测试框架可以帮助发现可能导致崩溃或其他安全问题的未定义行为。 虽然不可能用模糊测试找到所有的错误,但它可以成为发现和修复许多常见类型问题的有效方法。 它经常被用来测试那些处理来自不受信任来源的输入或可能有意外输入的程序。

模糊测试的使用

要测试的方法:

func Equal(a []byte, b []byte) bool {
	if len(a) != len(b) {
		return false
	}
    // 模拟意外情况
	if len(a) > 99 {
		panic("error")
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

在以_test结尾的测试文件中:

func FuzzEqual(f *testing.F) {
	f.Fuzz(func(t *testing.T, a []byte, b []byte) {
		Equal(a, b)
	})
}

使用命令go test . -fuzz 运行测试

在未发现错误时,控制台输出:

在这里插入图片描述

就注释而言,elapsed 是测试运行的时间,new interesting 是添加到语料库中提供独特结果的输入数量,execs 是运行的单个测试的数量。

遇到错误时:

在这里插入图片描述

Failing input written to 后面跟的、链接是发生错误的样例文件。

模糊测试的缺点

  • 模糊测试是通过随机输入的方式错误,并不能覆盖全部错误。
  • 模糊测试只能告知在某个输入的情况下会出错,具体错误还需要测试人员调试寻找。

Go WorkSpace

在开发个过程中,如果多个module同时开发,并且module之间存在相互依赖的关系,可能会出现频繁升级依赖包的问题。

有如下场景:

在这里插入图片描述

一个项目同时在本地开发两个模块,A和B,并且A依赖B,当B升级后,A如何升级自己依赖的包?

  1. 将module B 添加tag push到代码仓库,moudle 使用个go get 命令重新拉取。显然这种方法十分麻烦,A每次升级依赖包都需要进行一遍这样的流程。

  2. 可以使用go mod 的replace 命令,直接使用本地的最新代码,将A的go.mod进行如下更改:

    module example.com/A
    
    go 1.18
    
    require example.com/B v1.0.0
    
    replace example.com/B => ../B
    

    使用replace 命令后,尽管module B更新了 ,module A也可以使用最新的代码。但是同样存在一个问题,其他开发者下载该代码后,在编译时会报错,因为他的本地可能没有module B的代码。所以在使用这种方法时,在提交代码时要将replace 命令删除。

为了解决go mod 无法很好处理本地依赖包频繁升级的问题,go 1.18引入了go workspace机制。

在A和B模块的父目录执行命令go word init ./A ./B ,就会生成一个go .work 文件,文件目录结构如下:

├── A
│   ├── A.go
│   └── go.mod
├── B
│   ├── B.go
│   └── go.mod
└── go.work

go.work 文件的内容如下:

go 1.18

use (
	./A
	./B
)

这样我们就可以在不修改go mod 情况下,访问本地其他模块的最新内容。

建立项目 workspace 工作区之后,对项目的依赖包的修改不再需要进行实时升级,只需要在本地进行修改,等到项目代码提交时,一并升级即可,使用时有点类似于go mod 的replace,但是提交时并不需要修改go mod文件。

更多推荐

刷一下算法

记录下自己的思路与能理解的解法,可能并不是最优解法,不定期持续更新~1.盛最多水的容器给定一个长度为n的整数数组height。有n条垂线,第i条线的两个端点是(i,0)和(i,height[i])。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。个人想法:就是找出x轴与y轴相

2023最新AI创作商用ChatGPT源码分享+支持AI绘画

一、SparkAI智能创作系统SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧!SparkAi程序使用Ne

华为OD机考算法题:篮球比赛

目录题目部分解读与分析代码实现题目部分题目篮球比赛难度难题目说明篮球(5V5)比赛中,每个球员拥有一个战斗力,每个队伍的所有球员战斗力之和为该队伍的总体战斗力。现有10个球员准备分为两队进行训练赛,教练希望2个队伍的战斗力差值能够尽可能的小,以达到最佳训练效果。给出10个球员的战斗力,如果你是教练,你该如何分队,才能达

进程,线程切换

目录Linux线程切换:Linux进程切换:进程切换和线程切换的区别虚拟地址空间切换耗时的原因Linux线程切换:Linux线程切换的实现涉及到操作系统的调度和线程上下文的切换。线程上下文包括程序计数器(PC)和寄存器值,以及线程的堆栈和堆栈指针等。操作系统通过调度器决定哪个线程将获得CPU时间片来执行。当一个线程被操

蓝桥杯 题库 简单 每日十题 day2

01卡片题目描述本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。小蓝有很多数字卡片,每张卡片上都是数字0到9。小蓝准备用这些卡片来拼一些数,他想从1开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。小蓝想知道自己能从1拼到多少。例如,当小蓝有30张卡片,其中0到9各3张,则小蓝可以

Vue记录(上篇)

Helloworld案例<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>初识Vue</title><!--引入Vue--><scripttype="text/javascript"src="./vue.js"></script><scr

linux-checklist命令行

常用的linux命令行:首先打开终端,可用Ctrl+Alt+T快捷键打开.1.一些简单的命令下面是一些常用的简单命令:日期date//显示当前时间cal//显示日历(一般是一整个月)磁盘df//查看磁盘剩余空间free//显示空闲内存数量结束终端exit幕后控制台幕后控制台是和终端仿真器环境相同,不过外表不太美观,在不

图像处理之频域滤波DFT

摘要:傅里叶变换可以将任何满足相应数学条件的信号转换为不同系数的简单正弦和余弦函数的和。图像信号也是一种信号,只不过是二维离散信号,通过傅里叶变换对图像进行变换可以图像存空域转换为频域进行更多的处理。本文主要简要描述傅里叶变换以及其在图像处理中的简单应用,并进行一些简单的实验来描述其相关性质。关键字:傅里叶变换,二维傅

JavaScript学习笔记03

JavaScript笔记03流程控制if判断和Java中if语句的使用方法相同。例:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><script>"usestrict";letscore=90;if(score==

11、Kubernetes核心技术 - Service

目录一、概述二、Endpoint三、Service资源清单四、Service类型4.1、ClusterIP4.2、NodePort4.3、LoadBalancer4.4、ExternalName五、Service使用5.1、ClusterIP5.1.1、定义Pod资源清单5.1.2、创建Pod5.1.3、定义Servi

【从零学习python 】74. UDP网络程序:端口问题与绑定信息详解

文章目录udp网络程序-端口问题UDP绑定信息总结进阶案例udp网络程序-端口问题在运行UDP网络程序时,会遇到端口号会变化的情况。每次重新运行网络程序后,可以观察到运行中的“网络调试助手”显示的数字是不同的。这是因为该数字标识了网络程序的唯一性,系统在重新运行时会随机分配端口号。需要注意的是,在网络程序运行过程中,该

热文推荐