Skip to content

入门

Go 运行环境

  • GOROOT: Go 的安装路径
  • GOPATH: 当前用户 HOME 目录/go ~/go $HOME/go,目前第三方包安装目录,第三方包如果 install 就要编译可执行文件,就放在 bin 目录中
  • PATH: 增加了~/go/bin 目录,等价于 GOPATH + bin,bin(binary)二进制,go 可执行文件所在目录

命名方式

go 变量、常量、自定义类型、包、函数的命名方式必须遵循以下规则:

  1. 首字符可以是任意 Unicode 字符或下划线
  2. 首字符以外可以是任意 Unicode 字符、下划线或数字
  3. 名字的长度无限制

命名规范

  • 标识符采用 CamelCase 驼峰命名法
    • 如果只在包内可用,就采用小驼峰命名
    • 如果要在包外可见,就采用大驼峰命名
  • 简单循环变量可以使用 i、j、k、v 等
  • 条件变量、循环变量可以是单个字母或单个单词,Go 倾向于使用单个字母,Go 建议使用更短小
  • 常量驼峰命名即可
    • 在其它语言中,常量多使用全大写加下划线的命名方式,Go 语言没有这个要求
    • 对约定俗成的全大写,例如 PI
  • 函数/方法的参数,返回值应是单个单词或者单个字母
  • 函数可以是多个单词命名
  • 类型可以是多个单词命名
  • 方法由于调用时会绑定类型,所以可以考虑使用单个单词
  • 包以小写单词命名,包名应该和导入路径的最后一段路径保持一致
  • 接口优先采用单个单词命名,一般加 er 后缀,Go 语言推荐尽量定义小接口,接口也可以组合

关键字

关键字----
breakdefaultfuncinterfaceselect
casedefergomapstruct
chanelsegotopackageswitch
constifrangetypecontinue
forimportreturnfallthroughvar

保留字

常量数据类型---函数--
trueintuintuintptrboolmakecopyimag
falseint8uint8float32bytelenclosepanic
iotaint16uint16float64runecapdeleterecover
nilint32uint32complex128stringnewcomplex-
-int64uint64complex64errorappendreal-

算数运算符

运算符描述运算符描述运算符描述运算符描述运算符描述
+相加-相减*相乘/相除%求余

关系运算符

运算符描述
==检查两个值是否相等,如果相等就返回 true,否则返回 false
!=检查两个值是否不相等,如果不相等就返回 true,否则返回 false
>检查左边值是否大于右边值,如果是返回 true,否则返回 false
>=检查左边值是否大于等于右边值,如果是返回 true,否则返回 false
<检查左边值是否小于右边值,如果是返回 true,否则返回 false
<=检查左边值是否小于等于右边值,如果是返回 true,否则返回 false

逻辑运算符

运算符描述
&&逻辑 AND 运算符:如果两边的操作数都是 true,则为 true,否则为 false
||逻辑 OR 运算符:如果两边的操作数有一个为 true,则为 true,否则为 flase
!逻辑 NOT 运算符:如果条件为 true,则为 false,否则为 true

位运算符(比较二进制位数)

运算符描述
&参与运算的两位数各对应的二进位相与(两位均为 1 才为 1)
|参与运算的两位数各对应的二进位相或(两位有一个为 1 就为 1)
^参与运算的两位数各对应的二进位相异或,当两对应的二进位相异时,结果为 1(两位不一样则为 1)。作为一元运算符时表示按位取反,符号位也跟着变。
<<左移 n 位就是乘以 2 的 n 次方。a<<b 是把 a 的各二进位全部左移 b 个位置
>>右移 n 位就是除以 2 的 n 次方。a>>b 是把 a 的各二进位全部右移 b 个位置

补码

-二进位十进位值
源码0 1 0 15
按位取反1 0 1 0-
末位加 11 0 1 1-5

位运算

-&|^
操作数 10 1 0 10 1 0 10 1 0 1
操作数 20 1 1 00 1 1 00 1 1 0
结果0 1 0 00 1 1 10 0 1 1

异或运算:^1 1 1 0 = 1 0 0 1,除了最高位符号位不变以外,其它都从 0 变 1 或者 1 变 0

go
// %b代表二进制,%d代表十进制
func bitOp() {
    //获取系统架构和系统位数
	fmt.Printf("os arch %s,int size %d\n", runtime.GOARCH, strconv.IntSize)
	//260=2^8+2^2=100000100
	fmt.Printf("260 %b\n", 260)
	//二进制:110&101=100,十进制:4
	fmt.Printf("二进制:%b,十进制%d\n", 6&5, 6&5) 
	//二进制:110&101=111,十进制:7
	fmt.Printf("二进制:%b,十进制%d\n", 6|5, 6|5) 
	//二进制:110&101=011,十进制:3
	fmt.Printf("二进制:%b,十进制%d\n", 6^5, 6^5) 
	//二进制:101>>2=001,十进制:1
    fmt.Printf("二进制:%b,十进制%d\n", 5>>2, 5>>2) 
	//二进制:101<<2=10100,十进制:20
	fmt.Printf("二进制:%b,十进制%d\n", 5<<2, 5<<2) 
}

func main() {
	bitOp()
}
-原运算符操作运算后备注
正数右移0 1 0 1>>20 0 0 1高位补 0
正数左移0 1 0 1<<20 1 0 0低位补 0
负数右移1 1 0 1>>21 1 1 1高位补 1
负数左移1 1 0 1<<20 1 0 0低位补 0,负数左移后不一定为负数

赋值运算符

运算符描述运算符描述
=将右值赋值给左值<<=左移后赋值
+=相加后再赋值>>=右移后赋值
-=相减后再赋值&=按位与后赋值
*=相乘后再赋值|=按位或后赋值
/=相除后再赋值^=按位异或后赋值
%=求余后再赋值--

变量类型

类型go 变量类型fmt 输出
整形int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64%d
浮点型float32 float64%f %e %g
复数complex128 complex64%v
布尔型bool%t
指针uintptr%d %p
引用map slice channel%v
字节byte%d
任意字符rune%d
字符串string%s
错误error%v
检测数据类型%V

变量初始化

  • 如果声明后未显式初始化,数值型初始化 0,字符串初始化为空字符串,布尔型初始化为 false,引用类型、函数、指针、接口初始化为 nil
go
  var a string='America'
  var a,b int=3,7
  var a="America"//类型推断
  var a,b="America",7//类型推断
  • 函数内部的变量(非全局变量)可以通过:=声明并初始化
go
  a:=3
  • 下划线表示匿名变量,匿名变量不占命名空间,不会分配内存,因此可以重复使用
go
  _=2+4

常量

  • 常量在定义时必须赋值,且程序运行期间其值不能改变(命名建议大写)
  • Go 里面常量不能为数组, const a = [2]int{1,2} ,这样是不被允许的,因为数组的容器内容会变化,不能在编译期明确得确定下来.
go
  const PI float32=3.1415926
  const(
	PI=3.1415926
	E=2.71
  )//可以这样子定义常量
  const(
	a=100
	b  //100,跟上一行的值相同
	c  //100,跟上一行的值相同
  )

iota

  • iota 定义成批常量,iota 从 0 开始,从成批的第一行开始
go
  const(
	a = iota   //0
	b        //1
	c        //2
	d        //3
  )
  const(
	a = iota   //0
	b        //1
	_        //2
	d        //3
  )
  const(
	a = iota   //0,iota = 0
	b = 30		//30 ,iota = 1
	c = iota   //2,假如c不赋值iota,那么c=30,和上一行相同
	d        //3
  )
  const (
	m = 100	// 100 ,iota = 0
	n	// 100, iota = 1
	a = iota * 2	//2 * 2 = 4
	b	// 3 * 2 = 6
	c	// 4 * 2 = 8
	d	// 5 * 2 = 10
  )
  const(
	_ = iota			//iota=0
	KB = 1<< (10*iota) //iota=1
	MB= 1 << (10*iota) //iota=2
	GB= 1 << (10*iota) //iota=3
	TB= 1 << (10*iota) //iota=4
  )
  const(
	a,b = iota + 1,iota + 2	//1,2 iota=0,0+1,0+2
	c,d					//2,3 iota=1,1+1,1+2
	e,f					//3,4 iota=2,2+1,2+2
  )

字面量

  • 字面量:没有出现变量名,直接出现了值。基础类型的字面量相当于常量。
go
  fmt.Printf("%t\n",04 == 4.00) //用到了整型字面量和浮点型字面量
  fmt.Printf("%v\n",.4i) //虚数字面量0.4i
  fmt.Printf("%t\n",'\u4f17' == '') //Unicode和rune字面量比较
  fmt.Printf("Hello\nWorld\n!\n") //字符串字面量

变量作用域

  • 全局变量,大写字母开头,所有地方都可以访问,跨 package 访问时需要带上 package 名称
  • 全局变量,小写字母开头,仅本 package 内都可以访问
  • 局部变量,仅本函数内可以访问,内部声明的变量可以跟外部声明的变量有冲突,以内部的优先级更高,内部对 b 的修改不影响外部的 b 的值
  • 仅函数内部可以使用:=快速定义变量,全局定义变量必须使用 var/const 定义。
  • 一个 package(文件夹)下,包名可以和 package(文件夹) 名称不一样,但是文件夹下面的文件设定的包名必须命名一致
go
  var(
	A=3		//全局变量,大写字母开头
	b=4		//全局变量,小写字母开头
  )

  func foo(){
	b:=5	//局部变量,仅本函数内可以访问
	{
		b:=6	//仅{}圈定的作用域内可以访问
	}
  }

注释的形式

  • 单行注释,以//打头
  • 多行注释,连续多行以//打头,或者在段前使用/*,段尾使用*/
  • 多行注释之间不能出现空行
  • NOTE:引人注意,TODO:将来需要优化,Deprecated:变量或函数强烈建议不要再使用
  • 注释行前加缩进即可写 go 代码

注释的位置

  • 包注释: 在 package xxx 的上方,一个包只需要在一个地方写包注释,通常会专门写一个 doc.go,里面只有一行 package xxx 和关于包的注释。
  • 结构体注释: 在 type xxx struct 上方
  • 函数注释: 在 func xxx()上方
  • 行注释: 在行上方或右侧

运行go doc 包名后,控制台会输出包的注释,以及包内的以大写首写命名的全局变量及函数

godoc

  • godoc 可以为项目代码导出网页版的注释文档
  • 需要先安装 go install golang.org/x/tools/cmd/godoc@latest
  • 终端输入启动文档: godoc -http=:6060
  • 用浏览器访问:localhost:6060