go中常见的错误-以及泛型

news/2024/7/27 8:04:00/文章来源:https://blog.csdn.net/qq_40432598/article/details/135566899

https://github.com/teivah/100-go-mistakes#table-of-contents
nil Map
map记得要make初始化, slice可以不用初始化!

func main() {
//assignment to nil map
var course map[string]string //如果不初始化,就会为nilcourse["name"] = "go体系课"
}

结构体空指针
空结构体和结构体空指针可不一样

type Course struct {Name stringDesc string
}
func (c *Course) String() float64 {return c.Name + c.Desc
}
func main() {var c *Course //无效的内存地址或空指针解引用fmt.Println(c.String())
}
//结构体空指针 指针类型一定要初始化,否则nil
//var c *Couser 
c := &Couser{} // new(Couser)

使用对循环迭代器变量的引用 - 大坑!
在 Go 中,循环迭代器变量是一个单一的变量,在每个循环迭代中取不同的值。这如果使用不当,可能会导致非预期的行为。

func main() {var out []*intfor i := 0; i < 3; i++ {out = append(out, &i)}fmt.Println("Values:", *out[0], *out[1], *out[2])fmt.Println("Addresses:", out[0], out[1], out[2])
}
func main() {var out []*int//for循环的临时变量会复用for i := 0; i < 3; i++ {out = append(out, &i)}fmt.Println(out) //[0xc00000a0c8 0xc00000a0c8 0xc00000a0c8]for _, value := range out {fmt.Println(*value) //3 3 3}
}

解决办法

func main() {var out []*intfor i := 0; i < 3; i++ {tmpi := iout = append(out, &tmpi)}fmt.Println("Values:", *out[0], *out[1], *out[2])fmt.Println("Addresses:", out[0], out[1], out[2])
}

原因是:在每次迭代中,我们将 i 的地址追加到 out 切片中,但由于它是同一个变量,我们实际上追加的是相同的地址,该地址最终包含分配给 i 的最后一个值。所以只需要拷贝一份,让两者脱离关联就可以了。同样的,如果这里是for循环然后启动多个goroutine, 如下:

package main
import ("fmt""strconv""time"
)func main() {goodsID := []uint64{1, 2, 3, 4, 5}for _, id := range goodsID {go func() {fmt.Println("正在查询商品:" + strconv.Itoa(int(id)))}()}time.Sleep(time.Second * 5)
}

注意:这种bug在goland中一般会提醒,
常用的解决办法:

import ("fmt""strconv""time"
)func main() {goodsID := []uint64{1, 2, 3, 4, 5}for _, id := range goodsID {tmp := idgo func() {fmt.Println("正在查询商品:" + strconv.Itoa(int(tmp)))}()}time.Sleep(time.Second * 5)
}
package mainimport ("fmt""strconv""time"
)func main() {goodsID := []uint64{1, 2, 3, 4, 5}for _, id := range goodsID {//值传递go func(id uint64) {fmt.Println("正在查询商品:" + strconv.Itoa(int(id)))}(id)}time.Sleep(time.Second * 5)
}

go如何使用泛型

package mainfunc Add[T int | int32 | float32 | float64 | uint64](a, b T) T {return a + b
}// IAdd  没有泛型之前
func IAdd(a, b interface{}) interface{} {switch a.(type) {case int:return a.(int) + b.(int)case int32:return a.(int32) + b.(int32)case float32:return a.(float32) + b.(float32)}return nil
}func main() {//print(Add[float32](1.2, 2.2))t := IAdd(1, 2).(int)print(t)
}

泛型的常见用法

package maintype Mymap[KEY int | string, VALUE float32 | float64] map[KEY]VALUEtype Man struct {
}type Woman struct {
}type Company[T Man | Woman] struct {Name stringCEO  T
}type MyChannel[T int | string] chan T// WowStruct 类型嵌套
type WowStruct[T string | int, S []T] struct {A TB S
}func main() {/*m:=Mymap[int,float32]{}*///company := Company[Man]{//	Name: "chengpeng",//	CEO:  Man{},//}////company1 := Company[Woman]{//	Name: "chengpeng",//	CEO:  Man{},//}var c MyChannel[string]
}

泛型的错误用法

//错误用法1 类型参数不能单独使用
//type CommonType[T int | string] Ttype CommonType[T int | string] []T//错误用法2 无效的数组绑定 'T *int | string',必须是一个常量表达式
//type CommonType1[T *int | string] []Ttype CommonType1[T interface{ *int } | string] []T

匿名接口体不支持泛型–错误用法3

test:= struct[t int|string] {Name stringAge int
}{}

匿名函数不支持泛型–错误用法3

fn := func[T int | float64](a, b T) {
}

泛型不支持switch断言,但是可以用反射去做做法不提倡—错误用法4

func Add1[T int | int32 | float32 | float64 | uint64](a, b T) T {v := reflect.ValueOf(a)switch v.Kind() {case reflect.Int:print("int type")}return a + b
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_925889.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[oeasy]python005_退出游乐场_重启游乐场_系统态shell_应用态_quit

0005_ 退出游乐场_重启游乐场_系统态shell 退出终端_重启游乐场_shell_quit &#x1f94a; Python 回忆 上次 了解了 python进入了 python 游乐场 在游乐场 可以做 简单的计算还可以做 乘方运算 数字特别大之后 游乐场 会迟疑一下不过 最终 还是能算出来 可以让数字 更大一…

Vue学习笔记3--全局事件总线

Vue学习笔记3—全局事件总线 1.全局事件总线可以实现任意组件间通信 X需具备的条件&#xff1a; 所有的组件都要能看见X可以调用$on $off $emitVue.prototype.x {a:1, b:2} 可以被所有组件看见VueComponent.protoype.proto Vue.prototype组件实例对象(vc)可以访问到Vue原型上…

Java多线程并发篇----第十八篇

系列文章目录 文章目录 系列文章目录前言一、寄存器二、程序计数器三、PCB-“切换桢”四、上下文切换的活动五、引起线程上下文切换的原因前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了…

QT软件在线安装与维护

一.安装 安装QT开发环境分离线安装和在线安装两种方式&#xff0c;具体步骤如下&#xff1a; QT官网注册账号----下载安装包-----安装-----选择要安装的版本与开发包----版本维护 注意&#xff1a;Qt5.14.2是最后提供二进制安装包的版本&#xff0c;后面的版本都需要在线安装…

小程序系列--7.页面配置以及网络数据请求

一. 页面配置 1.页面配置文件的作用 小程序中&#xff0c;每个页面都有自己的 .json 配置文件&#xff0c;用来对当前页面的窗口外观、页面效果等进行配置。 2. 页面配置和全局配置的关系 3. 页面配置中常用的配置项 二、网络数据请求 1. 小程序中网络数据请求的限制 2. 配…

数据分析中常用的指标或方法

一、方差与标准差二、协方差三、皮尔逊系数四、斯皮尔曼系数 一、方差与标准差 总体方差 V a r ( x ) σ 2 ∑ i 1 n ( x i − x ˉ ) 2 n ∑ i 1 n x i 2 − n x ˉ 2 n E ( x 2 ) − [ E ( x ) ] 2 Var(x)\sigma^2\frac {\sum\limits_{i1}^{n} (x_i - \bar{x})^2} {n…

SQL性能分析手段

SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供整个服务器执行sql的状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff1a; -- session 是查看当前会话 ; -- globa…

数据结构排序二叉树(下)

哎,调了几天深度学习模型,今天来更新排序二叉树 文章目录 前言 一、排序二叉树的结构定义 二、在排序二叉树添加数据 三、定义创建排序二叉树函数 四、查找一棵二叉排序树中的结点x的所在层数 五、删除二叉排序树中T关键字x的节点 六、查找二叉排序树中的所有小于key的关…

【小笔记】算法训练基础超参数调优思路

【学而不思则罔&#xff0c;思维不学则怠】 本文总结一下常见的一些算法训练超参数调优思路&#xff08;陆续总结更新&#xff09;&#xff0c;包括&#xff1a; batchsize学习率epochsdropout&#xff08;待添加&#xff09; Batch_size 2023.9.29 简单来说&#xff0c;较…

Kotlin程序设计(二)面向对象

Kotlin程序设计中级篇 我们在前面已经学习了Kotlin程序设计的基础篇&#xff0c;本章我们将继续介绍更多Kotlin特性&#xff0c;以及面向对象编程。 函数 其实函数我们在一开始就在使用了&#xff1a; fun main() {println("Hello World") }我们程序的入口点就是…

day3:基于UDP模型的简单文件下载

思维导图 tftp文件下载客户端实现 #include <head.h> #define SER_PORT 69 #define SER_IP "192.168.125.223" int link_file() {int sfdsocket(AF_INET,SOCK_DGRAM,0);if(sfd-1){perror("socket error");return -1;}return sfd; } int filedownloa…

【Spring Cloud Alibaba】Sentinel 服务熔断与流量控制

目录 前言 一、Sentinel 入门 1.1 什么是 Sentinel ? 1.2 微服务集成 Sentinel 1.3 安装Sentinel控制台 二、Jmeter 压力测试工具 2.1 Jmeter 介绍 2.2 Jmeter 安装 2.3 接口测试 三、Sentinel 使用 3.1 限流规则 3.1.1 warm up(预热模式) 3.1.2 排队等待 3.1.3…

mathtype2024版本下载与安装(mac版本也包含在内)

安装包补丁主要是mathtype的安装包&#xff0c;与它的补丁。 详细安装过程&#xff1a; step1&#xff1a; 使用方法是下载完成后先安装MathType-win-zh.exe文件&#xff0c;跟着步骤走直接安装就行。 step2&#xff1a; 关闭之后&#xff0c;以管理员身份运行MathType7PJ.exe…

【数据结构和算法】反转链表

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;迭代&#xff08;双指针&#xff09; 2.2 方法二&#xff1a;递归 三、代码 3.…

survey和surveyCV:如何用R语言进行复杂抽样设计、权重计算和10折交叉验证?

一、引言 在实际调查和研究中&#xff0c;我们往往面临着样本选择的复杂性。复杂抽样设计能够更好地反映真实情况&#xff0c;提高数据的代表性和可靠性。例如&#xff0c;多阶段抽样可以有效地解决大规模调查的问题&#xff0c;整群抽样能够在保证样本的随机性的同时减少资源消…

网络安全全栈培训笔记(53-WEB攻防-通用漏洞跨域CORS资源JSONP回调域名接管劫持)

第54天 WEB攻防-通用漏洞&跨域CORS资源&JSONP回调&域名接管劫持 知识点&#xff1a; 1、子域名接管检测&探针&利用 2、C0SP跨域资源检测&探针&利用 3、JSONP跨域回调-检侧&探针&利用 #前置知识点&#xff1a; 同源策路(SOP),“同源”包…

centos7配置时间同步网络时间

centos7配置时间同步网络时间 1、安装 NTP 工具。 sudo yum install -y ntp2启动 NTP 服务。 sudo systemctl start ntpd3、将 NTP 服务设置为开机自启动。 sudo systemctl enable ntpd4、验证 date

【特征工程】分类变量:MultiLabelBinarizer对多标签数据进行编码

MultiLabelBinarizer 说明介绍 1. MultiLabelBinarizer 是什么&#xff1f; MultiLabelBinarizer是scikit-learn库中的一个用于处理多标签数据的编码器。通常用于将多标签的分类任务中的标签转化为二进制形式&#xff0c;便于机器学习模型的处理。该编码器的主要目标是将每个…

【网络安全】【密码学】【北京航空航天大学】实验一、数论基础(上)【C语言和Java实现】

实验一、数论基础&#xff08;上&#xff09; 一、实验目的 1、通过本次实验&#xff0c;熟悉相关的编程环境&#xff0c;为后续的实验做好铺垫&#xff1b; 2、回顾数论学科中的重要基本算法&#xff0c;并加深对其的理解&#xff0c;为本学期密码学理论及实验课程打下良好…

《ARM Linux内核源码剖析》读书笔记——0号进程(init_task)的创建时机

最近在读《ARM Linux内核源码剖析》&#xff0c;一直没有看到0号进程&#xff08;init_task进程)在哪里创建的。直到看到下面这篇文章才发现书中漏掉了set_task_stack_end_magic(&init_task)这行代码。 下面这篇文章提到&#xff1a;start_kernel()上来就会运行 set_task_…