热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

golang新手不注意可能会出现的一些小问题

最近在学习golang,发现了一些新手们需要注意的小问题,下面这篇文章主要给大家介绍了关于golang新手不注意可能会出现的一些小问题,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。

go简介

语言哲学

C语言是纯过程式的,这和它产生的历史背景有关。Java语言则是激进的面向对象主义推崇者,典型表现是它不能容忍体系里存在孤立的函数。而Go语言没有去否认任何一方,而是用批判吸收的眼光,将所有编程思想做了一次梳理,融合众家之长,但时刻警惕特性复杂化,极力维持语言特性的简洁,力求小而精

Go语言反对函数和操作符重载(overload),而C++、Java和C#都允许出现同名函数或操作符,只要它们的参数列表不同。

其次,Go语言支持类、类成员方法、类的组合,但反对继承,反对虚函数(virtual function)和虚函数重载。确切地说,Go也提供了继承,只不过是采用了组合的文法来提供

最近在整理之前写程序,学习时所记录的有道云笔记,发现一些有意思的小点跟大家分享一下。如有错误请大家给指出

一、闭包 defer

闭包(匿名函数)

func test(){
 i, n := 1 ,2;
 defer func(a int){
  fmt.Println("defer:", a , n); //n被闭包引用
 }(i) //复制i的值
 i , n = i+1,n+2;
 fmt.Println(i , n);
}

我们看一下结果:

2 4
defer: 1 4

为什么会这样?是因为闭包复制的是原对象指针,出现了延迟引用现象。我们在使用闭包的时候要注意这个问题,同样在for 循环中 也会出现类似现象。

二、Map

前一段时间在论坛看到一个问题

type Data struct{
 AABB [2]float64
}
var m map[string]Data = make(map[string]Data,1)
m["xxx"] = Data{}
m["xxx"].AABB[0]=1.0
m["xxx"].AABB[1]=2.0
#以上代码go build 通不过,错误提示cannot assign to m["xxx"].AABB[0]

这是一个网友给出的答案

type Data struct{
 AABB [2]float64
} 
m := make(map[string]*Data,1)
m["xxxx"] = Data{}
m["xxxx"].AABB[0] = 1.0
m["xxxx"].AABB[1] = 2.0
#这样写就对了,你的 m["xxxx"] 返回的是值,不是一个可取地址的变量

这个网友的答案可以编译成功,但是不可取,他犯了很多新手都容易出现的问题

why?Golang中的map元素属性被设计为只读的,并不期望被修改,并且从 map 中取回的是一个value也是临时复制品。并且map是一个hash 结构,当hash扩容时,键值的存储位置就会发生改变。如果这个时候我们对 m["xxxx"].AABB[0] = 1.0 修改,不知道指针会发什么。大家有兴趣可以看看Go Hashmap内存布局和实现

如果我们想修改最好这样

type Data struct{
 AABB [2]float64
}
m := make(map[string]*Data,1)
m["xxxx"] = &Data{}
d := m["xxxx"]
d.AABB[0] = 1.0
d.AABB[1] = 2.0
m["xxxx"] = d

三、nil

先看一段代码,当然这种场景不常见,但是能让我们更好的理解nil

func t(){
 var i *int = nil;
 var n interface{} = i;
 fmt.Println(n==nil); //false
}

可能很多小伙伴都会有疑问都是nil 为啥会不相等。我们先分别看一下pointer,interface的结构体和当pointer,interface为nil时的结构

uintptr
type interfaceStruct struct {
  v *_value // 实际值
  t *_type // 实际值的类型信息
}
uintptr(0) == nil
type interfaceStruct struct {
  v:uintptr(0)
  t:uintptr(0)
} == nil

由此我们可以看出nil其实就是指针 interface的零值

这时候我们在来解释为啥为flase就很容易了

func t(){
 var i *int = nil; // (*int)nil
 var n interface{} = i; // interace{}((*int)nil)
 fmt.Println(n==nil); // type interfaceStruct struct {
                 //  v: uintptr(0),
                 //  t: (*int)
                 // }
}

官方文档规定可以为nil的类型还有 slice ,map ,channel ,function 。

可能有些朋友可能会问为啥没有error类型,那是因为error 只是程序预设的接口方法, err nil 也会出现类似的问题,官方有一个文档也给出了解释,传送门

type error interface { 
 Error() string 
}  

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。


推荐阅读
  • web页面报表js下载,web报表软件 ... [详细]
  • 本文讲述了一位80后的普通男性程序员,尽管没有高学历,但通过不断的努力和学习,在IT行业中逐渐找到了自己的位置。从最初的仓库管理员到现在的多技能开发者,他的职业生涯充满了挑战与机遇。 ... [详细]
  • 本文将详细探讨PHP中C的作用,并对比其他编程语言如Java和C的特点及其适用场景。 ... [详细]
  • 在运行于MS SQL Server 2005的.NET 2.0 Web应用中,我偶尔会遇到令人头疼的SQL死锁问题。过去,我们主要通过调整查询来解决这些问题,但这既耗时又不可靠。我希望能找到一种确定性的查询模式,确保从设计上彻底避免SQL死锁。 ... [详细]
  • 用C语言实现的科学计算器,支持2种常量,10种基本函数,Ans寄存器。相对来说拓展性应该是不错的,思路是首先化简复杂名称的函 ... [详细]
  • ipsec 加密流程(二):ipsec初始化操作
    《openswan》专栏系列文章主要是记录openswan源码学习过程中的笔记。Author:叨陪鲤Email:vip_13031075266163.comDate:2020.1 ... [详细]
  • 数据结构第三章,栈、队列、数组,期末不挂科指南,第3篇
    数据结构第三章,栈、队列、数组,期末不挂科指南,第3篇,Go语言社区,Golang程序员人脉社 ... [详细]
  • 在C语言程序开发中,调试和错误分析是确保代码正确性和效率的关键步骤。本文通过一个简单的递归函数示例,详细介绍了如何编写和调试C语言程序。具体而言,我们将创建一个名为 `factorial.c` 的文件,实现计算阶乘的功能,并通过逐步调试来分析和解决可能出现的错误。此外,文章还探讨了常见的调试工具和技术,如GDB和断点设置,以帮助开发者高效地定位和修复问题。 ... [详细]
  • golang字符串转Time类型问题小记
      最近在做项目中,遇到了golang字符串转Time类型的问题。调研后发现golang提供了俩种方式,即time.Parse跟time.ParseInLocation。俩种方式差 ... [详细]
  • 七、Golang之切片(slice)-由于数组的长度是固定的,所以有很多的局限性,所以今天讲切片,切片是一个拥有相同类型且长度可变的有序集合,切片和数组两种不同的数据类型,它是基于 ... [详细]
  • [Redis 系列]redis 学习六,redis 事务处理和监控事务
    【Redis系列】redis学习六,redis事务处理和监控事务写在前面我们学过的事务都是保证原子性的,但是redis的事务中执行多个指令,是不保证原子性的redis事务的本质就是 ... [详细]
  • Beanstalk 安装教程
    docker-compose文档ports一定要配置,否则外网无法访问beanstalkd:image:schicklingbeanstalkdcontainer_name:bea ... [详细]
  • Golang 递归打印杨辉三角
    packagemainimportfmtfuncmain(){YangHuiTriangle(10)}funcYangHuiTriangle(nint)[]int{i:n-1l ... [详细]
  • 怎么编译并运行golang程序
    怎么编译并运行golang程序?刚入门的朋友还不知道怎么编译运行golang程序,通过这篇文章的总结,希望你能学会书写你的第一个go语言程序。首先我们 ... [详细]
  • 使用 Go 和 ReactJS 构建聊天系统(三):设计我们的前端
    在本节中,我们将着眼于改进前端并充实该应用程序,使其看起来像一个正规的在线聊天应用程序。本节完成后的效果如下:基于组件的方法在React以及所有其他流行的前端框架中,我们倾向于将应 ... [详细]
author-avatar
jojo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有