年初的立的各种Flag,已经被我抛到九霄云外去了。2018年已经过去了一半,终于开始了第三篇文章,距离全年30篇的输出计划,仅剩27本,我很有“信心完成”剩下的部分。

2018年伊始,开始从PHP转到Go的开发方向,虽然说学习路线并不是非常陡峭,但是过程中遇到不少坑以及有意思的地方,忍不住想总结分享给大家。今天先来聊一聊Go中初始化变量的几种方式。

Go中初始化值类型的招式

Golang的数据类型可以分为:值类型引用类型,我先来总结一下Go中值类型(以 string 为例)的初始化方式:

var a1 string
fmt.Printf("a1: %#v \n", a1) // a1: ""var a2 *string
fmt.Printf("a2: %#v \n", a2) // a2: (*string)(nil)
// panic: runtime error: invalid memory address or nil pointer dereference
//fmt.Printf(**"a2: %#v \n"**, *a2)a3 := new(string)
fmt.Printf("a3: %#v \n", a3) // a3: (*string)(0xc42000e200)
fmt.Printf(**"a3: %#v \n"**, *a3) // a3: ""a4 := "hello"
fmt.Printf("a4: %#v \n", a4) // a4: "hello"a5 := string("hello")
fmt.Printf("a5: %#v \n", a5) // a5: "hello"a6 := &a5
fmt.Printf("a6: %#v \n", a6) // a6: (*string)(0xc42000e1e0)// 报错,cannot make type string
//a7 := make(string, 1)// 报错,cannot take the address of string("hello")
//a8 := &string("hello")

注释部分是输出的信息,可以看到有的结果打出来是个值,有的是一个指针。这一部分重点我只想说明两个点:
1. Go会自动将申明变量初始化为0值,所谓的0值是:int就是0,string就是空字符,bool就是false等
2. 对于通过new创建的变量,是一个指针,它与var声明的变量是不同的,var声明的变量仅是一个nil。而new(string) 为string分配一片内存,初始化为 0。通过上面注释的报错信息大家可以理解。

Go中初始化引用类型的招式

这是我想说的重点,Go中的引用类型仅有三种:::map:: ::slice:: ::channel::,这里举例就用slice来进行。

var s1 []string
fmt.Printf("s1: %#v\n", s1) // s1: []string(nil)
s1 = append(s1, "hello")
fmt.Printf("s1: %#v\n", s1) // s1: []string{"hello"}var s2 *[]string
fmt.Printf("s2: %#v\n", s2) // s2: (*[]string)(nil)s3 := []string{"a", "b", "c"}
fmt.Printf("s3: %#v\n", s3) // s3: []string{"a", "b", "c"}s4 := &[]string{}
fmt.Printf("s4: %#v\n", s4) // s4: &[]string{}s5 := &s3
fmt.Printf("s5: %#v\n", s5) // s5: &[]string{"a", "b", "c"}s6 := new([]string)
fmt.Printf("s6: %#v\n", s6) // s6: &[]string(nil)
// first argument to append must be slice; have *[]string
//s6 = append(s6, "hello") // 这是一个空引用的指针,所以报错s7 := make([]string, 0)
fmt.Printf("s7: %#v\n", s7) // s7: []string{}// 有毛病才用这种方式
s8 := new([]string)
*s8 = make([]string, 0)
fmt.Printf("s8: %#v\n", s8) // s8: &[]string{}arr := [5]string{"a", "b", "c"}
s9 := arr[:]
fmt.Printf("s9: %#v\n", s9) // s9: []string{"a", "b", "c", "", ""}

这里我重点分析一下s6、s7、s8这三种初始化方式。先说s6,使用的是new。

new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型为*T的内存地址:这种方法 返回一个指向类型为 T,值为 0 的地址的指针
这里所谓的值为0,并不是数值0,而是go的默认0值,对应 ::slice:: 就是nil。

在Go中绝对不会采用这种方式来初始化 ::slice:: 的,原因是为什么呢?我这里先简单说一下,是因为Go中::slice::是如下定义的:

type slice struct{array unsafe.Pointerlen   intcap   int
}

如果用 new 因为返回的是 *T 的内存地址,无法完成对 ::slice::的初始化,无法让slice正常使用,想要让他可以正常使用,就得像s8的处理方式一样,再用make对应 *T 进行一次初始化。如果这么干,你说是不是有毛病才用的方式?

slice 的初始化需要初始化 len、cap的值,让 array 指向一个数组的指针。完成这些初始化后,slice才能正常使用。

总结

关于自定义结构的初始化与上面string的初始化一样,map、channel与slice一样。大家可以自己写点代码试试
- 记住make只用于map,slice和channel,并且不返回指针。
- 要获得一个显式的指针,使用new进行分配,或者显式地使用一个变量的地址。

接下来计划分享的内容:
1. Go中值、引用、指针方面的知识,重点是函数参数的传参方式
2. Go中::slice::与::array::的亲密关系
3. Go中接口的知识,从::sort::的源代码角度来介绍

Go初始化变量的招式相关推荐

  1. 补习系列(21)-SpringBoot初始化之7招式

    目录 背景 1. @PostConstruct 注解 2. InitializingBean 接口 3. @Bean initMethod方法 4. 构造器注入 5. ApplicationListe ...

  2. Java正则速成秘籍(一)之招式篇

    目录 导读 概述 Pattern类 Matcher类 校验文本是否与正则规则匹配 案例:lookingAt vs find vs matches 查找匹配正则规则的文本位置 案例:使用start(). ...

  3. javascript招式总结

    前言 在平时的开发中,经常会遇到一些特殊情况,就需要一些招式来应对.这里总结一下自己常用到的一些小招式,有不足欢迎大家指出. 模块 var fuc1 = (function() {var a = 'h ...

  4. C++11-列表初始化/变量类型推导/范围for/finaloverride/默认成员函数控制

    C++11-列表初始化/变量类型推导/范围for/final&override/默认成员函数控制 零.前言 一.C++11简介 二.列表初始化 1.内置类型列表初始化 2.自定义类型列表初始化 ...

  5. java武功秘籍_Java正则速成秘籍(一)之招式篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  6. java速成慕课_Java正则速成秘籍之招式篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression) 是一种文本规则,可以用来 校验 . 查找 . 替换 与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文 ...

  7. java查找规律的方法_Java正则速成秘籍(一) - 招式篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  8. 统计学习的三个招式:模型、策略和算法

    统计学习的三个招式:模型.策略和算法 https://mp.weixin.qq.com/s/12yhAZ79i_ENAdtyOX63lQ 李航老师在统计学习方法中讲到:方法=模型+策略+算法 可以说模 ...

  9. c语言unused variable错误,这个错误可能的原因是你忘了初始化变量

    已结贴√ 问题点数:20 回复次数:2 这个错误可能的原因是你忘了初始化变量 function EMDGETK %计算Argon热传导系数 %采用快速Fouie变换求解EMD算法得到的热传导系数 %r ...

最新文章

  1. Linux 下的动态库、静态库与环境变量
  2. More Effective C++:理解new和delete
  3. jquery内核学习(6)--扩展实现extend
  4. 把时间当作朋友 随笔记
  5. lenovo L480 进入bios_重装系统重启后不引导,重装系统无法进入引导
  6. win7下反汇编程序程序基址改变问题
  7. session共享mysql_多服务器session共享之mysql共享
  8. C# 调用FLashPaper2(二)
  9. ManyToManyField的注意事项和如何建立索引
  10. linux使用什么ide编译安卓,抛弃IDE,使用gradle命令与vim构建安卓应用
  11. 报错:error LNK2001:unresolved external symbol _WinMain@16
  12. [翻译]jQuery 1.5.1 发布,全面支持IE9
  13. mongdb 模糊查询
  14. VLAN的概念和链路分类
  15. php解析torrent文件格式,bittorrent 种子文件结构解析
  16. Linux下PCI设备驱动程序开发
  17. 基于python网上订餐系统哪家好_网上订餐系统python程序代码_(完整版)基于安卓的网上订餐系统毕业设计...
  18. 10款微信公众平台相关的开源软件
  19. 文献阅读(40)ICLR2021-Combining Label Propagation and Simple Models Out-performs Graph Neural Networks
  20. 进击的速溶咖啡:当中国AI开始玩工业化

热门文章

  1. ghost还原固态硬盘_高级格式化_固态硬盘到底能不能使用Ghost软件?终于说明白了...
  2. dell笔记本外接显示器_笔记本连接显示器怎么设置【图文教程】
  3. 给定一个数组,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择某一天买入这只股票,并选择在未来的一个不同的日子卖出该股票。【LeetCode Hot 100】
  4. 楪祈机器人_饥荒 Inori楪祈人物MOD V20161211
  5. 支付宝小程序uni-app的map多边形polygons不显示问题解决
  6. design contains shelved or modified (but not repoured) polygons. the result....继续铺铜还是报警,解决方案如下:
  7. AD18运行PCB DRC显示一处警告, Design contains shelved or modified (but not repoured) polygons.
  8. 王者服务器维护8月四日,王者荣耀体验服弈星重做上线 8月4日停机更新
  9. 基于Springboot的漫画之家管理系统
  10. Lineage Logistics完成对 UTI Forwarding的收购