go学习笔记(三)——语法


1.变量
变量是每种语言都不可或缺的声明方式,go提供了以下几种声明方式
1 | var a string |
需要注意的是,在go语言中声明的变量如果在接下来作用域中不使用,编译时会报xxx declared and not used错
除了上述几种声明,go语言还可用分组声明的方式
1 | var( |
同时 go中还有一个特殊的变量,匿名变量(_)在表示接收但不会使用的变量
1 | dictValue := map(string)int{"test":1} |
当然除了上面的使用方式,匿名变量还有其他的作用,在稍后会做解释。
2.常量
常量可以是字符、字符串、布尔值或数值。不支持 推断赋值(:=)
1 | const constValue int =1 |
1 | package main |

从上面的代码中,可以看到常量也是支持分组定义和匿名变量的。还有一个很陌生的itoa。
iota代表了const声明块的行索引(下标从0开始),还有就是我们看到_和blue并没有赋值,输出的时候结果blue输出的3,这里是const的特性第一个常量必须指定一个表达式,后续的常量如果没有表达式,则和上一行的表达式相同。
3.指针
除了go语言没有提供指针运算,其余和C语言中的指针一致——保存了值的内存地址。
1 | var p *int //零值为nil |
1.
&操作符会生成一个指向其操作数的指针;*操作符表示指针指向的底层值。
2.由于go中函数都是值传递,所以经常使用指针传递的方式在函数中修改原有对象信息
4.流程控制
a.条件语句
条件语句主要有if...else...和switch。if...else...语句和其他语言的没有什么区别,go中增加在if语句定义变量,该变量的作用域为if...else内
switch语句,与其他语言最大的差异是,只会执行第一个命中case条件的程序段,不需要额外的braek跳出。
1 | package main |
fallthrough关键字可以使命中后的case继续执行
b.循环
go中只有一种循环的写法for 语句,基本语法同java和python。
1 | for <初始化语句>;<条件语句>;<后置语句>{ |
break和continue效果与其他语言一样,不做介绍
e.g. for循环例子
5.包
go程序是由多个包构成的,其中每个可执行的go程序都是从main包开始的,main保重还需要有程序入口main函数,相当于java中的 public static void main(String [] args)方法和python中的if __name__ == "main "函数,关于go中的main函数会在函数中介绍。
go程序中引入包使用import关键字,和python,java中用法类似;同时go中import依然支持分组的写法
1 | package main |
上面的代码中对于包的倒入有了几种不同方式,使用匿名(_)接包名导入的方式,表示导入该包,但是不可使用其导出方法,但会执行该包中的init方法;点操作是一种便捷方式,使用点操作导入的包,在使用其导出方法的的时候,可以不使用包名,直接使用导出的函数进行调用;最后import http "net/http"是给引入包起别名的一种方式,类似Python中的import xxx as xx。
注意:
1.大写字母开头的变量和函数是可导出的,即其他包可以读取,是公用变量,公有函数;
2.小写字母开头的不可导出,是私有变量,私有函数。
6.函数
函数同java中的方法,python中的函数,声明如下所示
1 | func <func_name>(param pramType ,...)(result reusltType,...){ |
与java不同的是,go中的函数可以有多个返回值,同时生命时返回值在入参的后边(有点像scala的语法)。
几个特殊的函数
main函数:go程序的入口函数,每个go包只能有1个或0个main函数
init函数:包导入的时候的初始化操作函数,有点像java中的构造函数
panic和revocer函数:go中的异常处理函数,类似 throw 和catch机制
defer关键字
在函数中可以使用defer关键字帮我们处理一些资源关闭和return前处理,defer的功能很像java中 finally的处理,不同之处在于defer像一个栈一样,当程序即将运行完当前函数作用域时,会更具defer声明顺序的逆序一直执行defer的内容。
1 | package main |

函数闭包
闭包是一个函数值,它引用了其函数体之外的变量,该函数可以访问并赋予其引用的变量的值。
1 | package main |
7.结构体
上次听到结构体这个名词还是在大一学c语言的时候,之后这个词的出镜率基本为0。go中的结构体声明和c异曲同工。
1 | type <structName> struct { |
在go结构体重有一种特殊的写法,如下代码所示
1 | package main |

上面代码中,声明了Human和Employee两个结构体,在Employee结构体通过匿名的方式引入了Human,这里可以理解成一种继承,当我们初始化Employee的变量employee 时,employee会拥有Human的所有属性;但是当父亲结构体和子结构体拥有相同的属性时,子结构体会覆盖服结构体的属性;如果需要修改父中的同名属性,如main函数第3行所示。go中可以通过结构体声明匿名的结构体属性,来实现继承。
8.方法(method)
方法就是一类带特殊的接收者参数的函数。
1 | package main |
9.interface
接口是由一组方法签名定义的集合。
1 | type <interfaceName> interface { |
接口也是值。它们可以像其它值一样传递。接口值可以用作函数的参数或返回值,保存了一个具体底层类型的具体值。
接口值调用方法时会执行其底层类型的同名方法。






