前言

上篇内容,介绍了如何在不同的系统上安装 Go 开发环境和部分参数的配置,也简单介绍了 package 的概念、导入方式和我对包的初始化过程的理解,关于初始化顺序的理解,可能有错误,后期会有修改,也希望大家能指出来,帮助我学习下,谢谢。

这篇内容,讲些基础的知识,比如变量的声明方式、变量的重声明和重命名区别。

变量的声明

Go 语言中,变量的声明有几种方式,如:

var i,j int = 1,2
var i,j = 1,"2"
i,j,k := 1,"2",true
var (
m int=4
n = "Golang"
r = true
)

这里面比较特殊的是 i,j,k := 1,"2",true ,这在 Go 语言里被称为短声明,它有一个特殊点,就是不能在包级作用域中使用,只能在函数或块中使用。这里涉及到我要讲的两个知识点,变量重声明重名变量

变量的重声明

什么是变量的重声明?让我们用个例子来解释吧:

var err error
n,err:=io.WriteString(os.Stdout,"Hello world!\n")

从代码中我们看到,err 在第一行被声明了,接着我们又使用短声明的方式重新给它了值,注意这里没有变量重名即变量覆盖,发生的是变量重声明,这些代码在一个代码块中,如果你不确定,可以输出下变量地址看看是否有改变。这里我们先注意下变量重声明的前提条件,如下:

  1. 由于变量的类型在初始化时就已经确定,所以再次声明时赋予的类型必须与原本的相同,否则编译报错。

  2. 变量的声明只能发生在同一个代码块中。如果是与不同的代码块的变量重名,那么就是变量重名了,下文会介绍。

  3. 变量的重声明只有在短变量声明时才会发生,否则便已报错。

  4. 被声明的变量必须有多个,而且其中至少有一个新变量,而且不能使用 _ 表示新变量。

上面提到了变量重名,如果你是个老鸟,那么你肯定知道,你可以略过这个例子了:

var name = "Tom"
{
name := []string{"Jerry"}
fmt.Printf("%v\n",name)
}
fmt.Printf("%s\n",name)

也许心细如你,发现了不同,没错这两次变量的声明发生在了不同的代码块,这次就是变量的覆盖了,好了现在我们可以总结下两者的区别了

  1. 变量的重声明必须在同一代码块中,注意是 同一代码
  2. 变量重声明是对同一变量的的多次声明,即变量只有一个。
  3. 变量重声明,不论多少次其类型始终一致,必须遵从它的次声明指定的类型。而重名变量则不存在类型一致的限制,可以是任意不同类型。
  4. 如果可重名变量所在代码存在直接或间接的嵌套关系v,那么肯定会存在“屏蔽”现象,而变量重声明不会。

数组和切片

数组(array)类型和切片(slice)类型,两者都属于集合类型,都是存储了某一类型的值,这么看貌似它们没有什么区别,先让我们通过几个简单的例子看下区别。

数组的长度在声明时就需要给定,以后对其的使用是不能改变其长度的,也就是说长度是类型的一部分。

比如[5]int与[6]int是不同的两种数组类型;然后切片的类型字面量中只有元素的类型,而没有其长度。换句话说,切片的长度可以随着其中的元素增长而增长,但不会随着减少而减少。让我们看下几个示例,如下:

// 一维数组
array1 :=[6]int
// 二维数组
array2 :=[10][20]string
// 这里还是数组,自动计算数组的长度
array3 :=[...]int{10,20,30,40}
// 切片,len()=cap()=1
slice1 :=[]int{1}
// 声明一个长度为5,但容量为10的string类型的切片,长度和容量都是可变。容量参数10可省略,那么该slice的容量跟长度一致都是5
slice3 := make([]string,5,10)
// 连续插入多个值,其实后面也是个slice
slice1=append(slice1,2,3,4)
// 从slice1第二个素开始取出两个并组成一个新的切片,slice1和slice2是共享一个底层数组的。len(slice2)=2,cap(slice2)=3
slice2:=slice1[1:3]
// 如果这里修改了slice2的第一个元素值,slice1会有变化么,想想,不确定的话可以自己尝试输出下
slice2[0]=-2
// 这里又声明了slice4,似乎与slice2有些区别,那么区别在哪呢?
slice4:=slice1[1:3:3]

看了上面的示例代码,也许对切片会有更多的疑惑,别急现在我们一一解答。

示例代码中 slice2:=slice1[1:3] 这里使用切片slice1创建了一个新切片,其长度 len(slice2)cap(slice2) 分别是2,3。为什么其容量是3呢?先解释下这个声明语句,slice1[1:3] 第一个值表示新切片开始的元素位置,这里是1,表示是从slice1的第二元素开始。第二个值表示开始的索引位置(1),加上希望包含的元素个数(2),1+2的结果就是3,所以第二个值就是3,但要注意这里是不包含第二个值代表的索引位置的值,这里是数学中前开后闭的区间。那么第二个切片的容量怎么计算的呢?由于两个切片共享同一个底层数组,底层数组的容量是4,由于slice2是从索引位置为(1)开始,那么slice2的容量就是4-1=3,所以容量就是3。由于这两个切片共享同一个底层数组,所以 slice2[0]=-2 语句是修改的底层数组的值,对应的slice1[1]位置的值也被修改。想一下下面的代码输出结果是什么?

slice1:=[]int{1,2,3,4}
slice2:=slice1[1:3]
slice2=append(slice2,5)
fmt.Printf("s1:%v\n",slice1)
fmt.Printf("s2:%v\n",slice2)

你想到的输出结果,跟下面一样么?

s1:[]{1,2,3,5}
s2:[]{2,3,5}

上面提到 slice2:=slice1[1:3] 中有第三个参数,新切片的容量,默认是可忽略的,此时新切片的容量是 cap(slice1)-1 。你也可以加入第三个参数,但你要记住它是不能超过底层数组的容量的,也不能小于第二个参数值否则编译报错,如 slice2:=slice1[1:3:3] ,此时新切片的容量变成了3-1=2,跟长度一致,但前提是cap(slice2)的容量不能超过底层数组的容量cap(slice1),也不能少于len(slice2)。想一下,第三个参数有什么作用呢?

Go学习笔记02的更多相关文章

  1. 软件测试之loadrunner学习笔记-02集合点

    loadrunner学习笔记-02集合点 集合点函数可以帮助我们生成有效可控的并发操作.虽然在Controller中多用户负载的Vuser是一起开始运行脚本的,但是由于计算机的串行处理机制,脚本的运行 ...

  2. 机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN)

    机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN) 关键字:邻近算法(kNN: k Nearest Neighbors).python.源 ...

  3. OpenCV 学习笔记 02 使用opencv处理图像

    1 不同色彩空间的转换 opencv 中有数百种关于不同色彩空间的转换方法,但常用的有三种色彩空间:灰度.BRG.HSV(Hue-Saturation-Value) 灰度 - 灰度色彩空间是通过去除彩 ...

  4. SaToken学习笔记-02

    SaToken学习笔记-02 如果排版有问题,请点击:传送门 常用的登录有关的方法 - StpUtil.logout() 作用为:当前会话注销登录 调用此方法,其实做了哪些操作呢,我们来一起看一下源码 ...

  5. Redis:学习笔记-02

    Redis:学习笔记-02 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 4. 事物 Redis 事务本 ...

  6. OGG学习笔记02

    实验环境:源端:192.168.1.30,Oracle 10.2.0.5 单实例目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1.模拟源数据库业务持续运行 2.配置OGG前 ...

  7. 《Master Bitcoin》学习笔记02——比特币的交易模型

    比特币的交易模型 模型基本描述 前面一篇学习笔记01提到了一个交易模型(第三章的内容),在第五章中,除了对这个模型做个详细介绍之外,其实和我上一篇理解的交易模型差不多,一个交易包含输入与输出,比特币是 ...

  8. [Golang学习笔记] 02 命令源码文件

    源码文件的三种类型: 命令源文件:可以直接运行的程序,可以不编译而使用命令“go run”启动.执行. 库源码文件 测试源码文件 面试题:命令源码文件的用途是什么,怎样编写它? 典型回答: 命令源码文 ...

  9. [原创]java WEB学习笔记02:javaWeb开发的目录结构

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  10. 类型和变量(C#学习笔记02)

    类型和变量 [C#类型和变量(原文参考官方教程)]https://docs.microsoft.com/zh-cn/dotnet/csharp/tour-of-csharp/types-and-var ...

随机推荐

  1. SVN图标不显示的解决几种方式

    系统安装的Tortoise SVN,不知道是不是安装了其他软件的缘故,造成SVN客户端功能可以正常使用,就是文件夹或文件的左下角不显示图标.故上网查找解决方法: 方法一: 升级到最新版本,基本是没用的 ...

  2. Android studio ocr初级app开发问题汇总(含工程代码)

    博客第一篇文章,稍作修改,增加文字介绍 开发目的 最近由于某些需求,需要在Android手机端实现OCR功能,大致为通过手机照相,识别出相片中的中文信息字段.但是由于新手光环+流程不熟悉,遇到了各种各 ...

  3. August 21st 2017 Week 34th Monday

    In fact, the happiest fairy tale is no more than the simple days we have together. 其实全世界最幸福的童话,也比不上我 ...

  4. linux setup 相关text mode图形配置工具的安装

    centos 6.4 x86_64 minimal安装后发现setup命令不可用 yum update yum install setup 安装完了还是不可用,不知为什么,难道装的那个包不对?yum ...

  5. 纯css3跑马灯demo

    我们写跑马灯一般都是用js控制定时器不断循环产生,但是定时器消耗比较大,特别是程序中很多用到定时器的时候,感觉有的时候比较卡.但是css3样式一般不会.这里主要的思路就是用css3代替js定时器实现一 ...

  6. css计数器 及 鼠标经过从中间扩散一个矩形(正方形长方形均可)

    <!DOCTYPE html> <html> <head> <title>css计数器--兼容IE8</title> <meta ch ...

  7. vue项目搭建笔记

    安装nodejs后, 首先安装淘宝镜像:npm install -g cnpm --registry=https://registry.npm.taobao.org 淘宝镜像安装成功后,安装vue脚手 ...

  8. redis和mecache和ehcache的特点

    最近项目组有用到这三个缓存,去各自的官方看了下,觉得还真的各有千秋!今天特意归纳下各个缓存的优缺点,仅供参考! Ehcache 在java项目广泛的使用.它是一个开源的.设计于提高在数据从RDBMS中 ...

  9. rocket-console控制台安装

    1.下载 github地址:https://github.com/apache/rocketmq-externals 2.选择稳定版本: 3.下载到本地:       环境需求 maven  jdk ...

  10. 修改网卡MAC地址后出现问题:device eth0 does not seem to be present, delaying initialization

    修改网卡MAC地址后出现问题:device eth0 does not seem to be present, delaying initialization   1.修改网卡对应的文件,将配置文件中 ...