第二章 程序结构

2.1 命名

在GO语言中,所有的变量名、函数、常量、类型、语句标号、包名都遵循一个原则:

名字必须以字母或者下划线开头,后面紧跟任意数量的字母数字下划线。区分大小写。

在GO语言中包含25个关键字:

| break   | default   | func   | interface | select |
| case    | defer     |  go    |  map      | struct |
| chan    | else      | goto   | package   | switch |
| const   |fallthrough|  if    | range     | type   |
| continue| for       | import | return    | var    |

注意:GO语言中没有while关键字…

在Go语言中大约有30多个预定义的名字,主要为内建的常量、变量以及函数。

内建常量:true false iota nil内建类型:int int8 int16 int32 int64uint uint8 uint16 uint32 uint64float32 float64 complex128 complex64bool byte rune string error内建函数:make len cap new append copy close deletecomplex real imag panic recover

一般情况情况下:名字的首字母大小写决定了名字在包外的可见性。如果包外可见,则使用以大写字母开头,如Println()
Go语言命名遵循"驼峰式"原则,即变量有多个字母混合组成时,首字母大写的方式,不是采用下划线分割的方式。

2.2 声明

声明语句定义了程序各种实体对象,以及他们的部分或者全部属性。Go语言中主要包含4种类型的声明语句:var、const、type、func,他们分别对应变量、常量、类型、函数实体对象的声明。

一个Go语言编写的程序对应一个或多个以.go为文件后缀名的源文件中。

  • 每个源文件以包的声明语句开始,说明该源文件是属于哪个包。
  • 包声明语句之后是import语句导入依赖的其它包,
  • 然后是包一级的类型、变量、常量、函数的声明语句,包一级的各种类型的声明语句的顺序无关紧要。

例如,下面的例子中声明了一个常量、一个函数和两个变量:

package mainimport "fmt"/*水的沸点*/
const boilingF = 212.0func main() {var f = boilingFvar c = (f - 32) * 5 / 9fmt.Printf("boiling point = %g°F or %g°C", f, c)
}

结果如下:

boiling point = 212°F or 100°C

函数和变量的使用如下:

package mainimport "fmt"func main() {const freezingF, boilingF = 32.0, 212.0fmt.Printf("%g°F = %g°C\n", freezingF, ftoc(freezingF))fmt.Printf("%g°F = %g°C\n", boilingF, ftoc(boilingF))}func ftoc(f float64) float64 {return (f - 32) * 5 / 9
}

运行结果:

32°F = 0°C
212°F = 100°C

2.3 变量

var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,而且设置变量的初始值。变量的声明语法如下:

var 变量名 类型 = 表达式

其中"类型"或者"=表达式"可以省略其中一个。

  • 如果省略"类型",则根据初始值表达式推导出变量的类型
  • 如果省略"=表达式", 则将其初始化为该类型的0值

在Go语言中,零值初始化机制可以保证每一个声明的变量都有一个很好的初始值,不存在未初始化的变量。

包级别声明的变量会在main入口函数执行前完成初始化,局部变量将会在声明语句被执行到的时候在完成初始化。
一组变量也可以通过条用一个函数,有函数的多个返回值来完成初始化。

    var f, err = os.Open("/usr/local/avi/xxoo.avi")/*os.Open return a file and an error*/

2.3.1 简短声明

在函数内部,有一个简短变量声明方式可用于声明和初始化局部变量。它以"名字:=表达式"形式声明变量。变量的类型根据表达式来自动推导。

简短声明因为简洁和灵活的特点,被广泛用于大部分局部变量的声明和初始化。

var形式的声明语句往往用于需要显式指定变量类型的地方,或者因为变量稍后重新复制而初始值无关紧要的地方。

i := 100
var boiling float64 = 100.0
var names []string
var err error
var p Point

与var形式声明变量语句一样,简短声明也可以用来声明和初始化一组变量:
i, j := 1, 2

简短声明有一个需要注意的地方:

变量 := 表达式

  • 简短声明左边的变量可能不是全部刚刚声明的,允许使用先前已经声明的变量,如果已经声明了,那么这里只是赋值操作。
  • 简短声明中必须至少要声明一个新的变量,否则无法编译通过。
  • 简短声明语句只有对已经存在的同级词法域声明过的变量才和赋值操作等价。
    fp, err := os.Open(xxx.avi)/* xxoo blabla*/newFp, err := os.Create(ooo.avi)

上面使用简短声明的方式没有语法错误,但是下面的简短声明则无法编译通过:

    fp, err := os.Open(xxx.avi)/* xxoo blabla*/fp, err := os.Create(ooo.avi)

2.3.2 指针

基本原则同C语言。

    x := 1p := &x
  • 任何类型的指针的零值都是nil
  • 在Go语言中,返回函数中的局部变量的地址也是安全的…

2.3.3 new函数

另一个创建变量的方法是调用用内建的new函数。
表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T。

    p := new(int)fmt.Println(*p)*p = 2fmt.Println(*p)

运行结果:

    02

用new创建变量和普通变量声明语句方式创建变量没有什么区别,除了不需要声明一个临时变量的名字外,我们还可以在表达式中使用new(T)。
使用new函数来声明变量比较少见。

在Go允许存在大小为0的数据,结构体…
new 是Go语言内置的变量名。

2.3.4 变量的生命周期

Go语言存在垃圾回收机制。
Go语言的自动垃圾收集器对编写正确的代码是一个巨大的帮助,但也并不是说你完全不用考虑内存了。
你虽然不需要显式地分配和释放内存,但是要编写高效的程序你依然需要了解变量的生命周期。
例如,如果将指向短生命周期对象的指针保存到具有长生命周期的对象中,特别是保存到全局变量时,会阻止对短生命周期对象的垃圾回收(局部变量逃逸)。

  • 局部变量逃逸
    var global *intfunc f(){var x intx = 1global = &x}

在Go语言中,上述代码是合法的,但是由于x是函数内的局部变量,却将其保存到全局变量中,导致声明周期延长。Go的术语称之为:“局部变量x从函数f中逃逸了”

2.4 赋值

赋值操作比较简单,直接举几个例子来说明:

    x = 1*p = trueperson.name = "Toney"count[x] = count[x] * scalecount[x] *= scale

赋值变量支持递增(++)和递减(--)语句。

自增和自减是语句,不是表达式,因此x = i++是不合法的。

    v := 1v++     //合法v--     //合法

2.4.1 元组赋值

元组赋值是同时对多个变量进行赋值的操作。
在赋值之前,赋值语句右边的所有的表达式会首先计算求值,然后在同一更新右边变量的值。

例如交换两个数据:

/*直接交换两个变量的值*/x,y = y,x  a[i],a[j] = a[j],a[i]/*多个变量进行赋值*/i,j,k = 1,2,3f, err = os.Open("golang.txt")v, ok = m[key]  //查找哈希MAPv, ok = x.(T)   //类型断言v, ok = <-ch    //接收通道数据

如果对于某个返回值不感兴趣,则可以使用’_'来代替,表示不关心此返回值:

    _, ok = m[key]           //返回2个值_, ok = mm.[""], false   //返回1个值_ = mm[""]               //返回1个值

2.4.2 可赋值性

赋值语句是显式的赋值形式

    medals := []string{"gold", "silver","water","soil"}

也可以单独每一个元素进行赋值:

    medals[0] = "gold"medals[1] = "silver"medals[2] = "water"medals[3] = "soil"

无论是显式赋值还是隐式赋值,等号两边的类型必须相同。

2.5 类型

变量或表达式的类型定义了对应存储值的属性特征。

格式如下:

type 类型名字 底层类型

  • 类型声明语句一般出现在包一级,如果新创建的类型名字首字符大写,则在外部包也可以使用。
  • 两个拥有不同类型的值无法直接进行比较

2.6 包和文件

  • Go语言中的包和其他语言的库或模块的概念类似,目的都是为了支持模块化、封装、单独编译和代码重用
  • 每个包都对应一个独立的名字空间。
  • 包还可以让我们通过控制哪些名字是外部可见的来隐藏内部实现信息。
  • 在Go语言中,一个简单的规则是:如果一个名字是大写字母开头的,那么该名字是导出的
  • 注:由于汉字不区分大小写,因此无法导出。

2.7 作用域

  • 一个声明语句将程序中的实体和一个名字关联,比如一个函数或一个变量。
  • 声明语句的作用域是指源代码中可以有效使用这个名字的范围。

作用域和生命周期是两个不同的概念:

  • 作用域对应源代码的文本区域,是一个编译时的属性
  • 变量的生存周期是指运行时变量存在的有效时间段,在此时间区域内,可以被其他部分引用。

注意事项:

  • Go中内部声明会屏蔽同名的外部声明,因此需要特别注意简短声明方式

《Go语言圣经》阅读笔记:第二章程序结构相关推荐

  1. Go语言圣经阅读-第二周

    Go语言圣经阅读-第二周 2.4. 赋值 使用赋值语句可以更新一个变量的值,最简单的赋值语句是将要被赋值的变量放在=的左边,新值的表达式放在=的右边. x = 1 // 命名变量的赋值 *p = tr ...

  2. 《go 语言圣经》笔记

    最近看了<go 语言圣经>这本书,发现 go 语言很有趣,对于语法就不必关注,主要记录了一些语言特性(相对于其他语言而言)的笔记. Go(又称Golang)是 Google 开发的一种静态 ...

  3. 极限编程阅读笔记--第二篇

    应本学期软件工程寒假作业,发表第二篇阅读笔记,读的书为<规划极限编程>,本次阅读了五到八章. 第五章:本章讲的是概述,在开发之前我们要总揽这个项目,看看他的开发周期和业务周期,一般开发周期 ...

  4. Go语言圣经阅读-第一周

    第一章 入门 本章介绍Go语言的基础组件.本章提供了足够的信息和示例程序,希望可以帮你尽快入门,写出有用的程序.本章和之后章节的示例程序都针对你可能遇到的现实案例.先了解几个Go程序,涉及的主题从简单 ...

  5. 【Go学习】go语言圣经学习笔记

    目录 前言 入门 前言 想扎扎实实的看看书,跟着书的目录结构走,记录看书笔记 The Go Programming Language Go语言圣经(中文版) 入门

  6. go channel 缓冲区最大限制_GO语言圣经学习笔记(八)Goroutines和Channels

    奋斗鸭!Day97 知识点 goroutinue 基本用法 golang非常深度的简化了goroutinue的使用方法,异常简单,门槛降低很多 // goroutinue 使用非常简单go f() G ...

  7. 深入理解 C 指针阅读笔记 -- 第二章

    Chapter2.h #ifndef __CHAPTER_2_ #define __CHAPTER_2_/*<深入理解C指针>学习笔记 -- 第二章*//*内存泄露的两种形式1.忘记回收内 ...

  8. 计算机网络阅读笔记——第二章物理层

    文章目录 思维导图 阅读笔记 1.物理层的基本概念 2.数据通信的基础知识 3.物理层下面的传输媒体 4.信道复用技术 5.数字传输系统 6.宽带接入技术 习题解答 1.常见问题与解答 2.习题与解答 ...

  9. Go语言圣经阅读-第三周

    2.7. 作用域 一个声明语句将程序中的实体和一个名字关联,比如一个函数或一个变量.声明语句的作用域是指源代码中可以有效使用这个名字的范围. 不要将作用域和生命周期混为一谈.声明语句的作用域对应的是一 ...

  10. 《Go语言圣经》笔记(1-4章)

    第一章.入门 第一章的命令行部分最后学!先学后面 1.hello world Go不需要加分号 "{" 符号必须和关键字func在同一行,不能独自成行.并且在 x+y 这个表达式中 ...

最新文章

  1. OpenCL编程详细解析与实例
  2. SparkSQL读取文件时,数据字段类型调整
  3. sql drop 简单操作(Mysql)
  4. Java方法中的参数太多,第8部分:工具
  5. Linux网络编程---I/O复用模型之poll
  6. 凤凰网php,凤凰网某应用sql注入漏洞_MySQL
  7. 沟通科技:将引领接入革命第三次浪潮
  8. Android学习笔记---文件的操作模式,各种模式之间的关系,以及沿用linux系统的安全性
  9. Hive已死,SparkSQL来啦~
  10. 从零开始学习python编程-从零开始的Python学习 -- 简单的练习题
  11. matlab2018安装摄像头驱动以及如何调用摄像头
  12. 介绍一个基于SpringBoot2的脚手架项目
  13. 2021年6月10日08点53分 SQL注入
  14. visio2016 数据库模型图_数据库相关术语整理
  15. 基于SSM的校园二手交易平台
  16. 机器学习之层次聚类(hierarchical clustering)
  17. 国外互联网公司大数据技术架构研究
  18. 2019腾讯广告算法大赛
  19. php 判断字数,php 如何统计中文字数
  20. kgb压缩_KGB Archiver可能是可用的最佳压缩工具吗? 还是最慢?

热门文章

  1. 斐波那契数列(Fibonacci)的三种JAVA解法
  2. 关于一些初级ACM竞赛题目的分析和题解(三)。
  3. 【通俗理解】开漏/开集,线与
  4. diabetes影响因子2017_2017年SCI影响因子发布,几家欢喜几家愁
  5. 以4%参数量比肩GPT-3!Deepmind 发布检索型 LM,或将成为 LM 发展新趋势!?
  6. 基于FPGA的自动售货机设计(EDA课程设计)(湖南科技大学)
  7. 数字密码锁设计(利用数字逻辑电路的电子密码锁)
  8. Layabox3d入门游戏视频教程
  9. 计算机软件图标不正常,电脑桌面软件图标显示异常
  10. iOS音频掌柜-- AVAudioSession