Go语言程序结构
一、Go语言程序元素
1). 标识符
- 标识变量、函数、自定义程序实体。
- 预定义标识符:
- 数据类型:
- bool (true和false)、
- byte、uint16、float32、float64、int、int8、int16、uint32、int32、int64、uint64、
- string、uint、uint8、uintptr
- 内建函数名:append、cap、close、complex、copy、delete、imag、len、make、new、panic、print、println、real、recover;
- 其他标识符:iota、nil、
_
- 数据类型:
_
叫作空标识符,一般用在变量声明与包的导入中,例如 Go 语言程序中,若存在一个没有使用的变量a,那么编译时会报错,因为Go语言要求存在实体必须使用,所以可以加一句_=a这样的代码,这样Go语言编译器会认为使用了a变量,也就不会报错了,而实际上并没有对变量a做任何操作。程序初始化后空标识符就会被释放。
- 标识符以字母a~z(大小写均可)或下画线_开头,后面可以是多个字母、下画线和数字
Go语言不允许在标识符中使用标点符号,例如@、$、%等一系列符号
- 区分大小写
2). 关键字
- 静态编译型语言,只有简单的25个。
- 包导入声明:
import package
- 程序实体声明与定义:
var type func interface map struct chan const
- 流程控制:
if continue for return go case goto switch select else break default defer fallthrough range
- 空接口:
_
3). 字面量
值的一种标记
- 基础数据类型值的各种字面量
- 用户构造的自定义复合数据类型的类型字面量
- 复合数据类型的值的复合字面量
被用来构造类型 Struct Array Slice Map
4). 分隔符
- 括号:括号、中括号、大括号
- 标点分隔符:小数点、逗号、分号、冒号、省略号
Go 语言语句结尾不需要分号,如果一行有个多语句则需要,但是别这样写!
5). 运算符以及优先级
- 一元运算符优先级高于二元运算符
- 二元运算符之间也有优先级
- 优先级相同从左到右
- 括号的优先级永远最高
-
++
--
是语句,不是表达式,没有优先级之说; - Go 摒弃了C++的运算符重载
6). 注释
// 注释
/* 注释 */
/*
注释
*/
二、常量
- 编译期已知固定值不会改变。
- 可定义为常量的数据类型:
- 数值:整型、浮点型、复数类型
- 布尔值
- 字符串
- 等等
- 关键字
const
- 格式
const identifier [type] = value
const Pi = 3.1415926
// 指定明确类型
const Pi2 float32 = 3.1415926
const Return = true
const hello = "Let`s go"
Go 语言中可以省略类型说明,Go编译器可以智能判断值的类型。
// 显示定义
const h string = "hello"
// 隐式定义
const w = "world"
- Go支持超长的小数位数,如果指定了为特定类型,比如float32,则会自动缩短为32b;float64则为64b
- Go支持反斜杠
\
,可以作为跨行连接符,类似Linux中的Shell命令换行连接
const Pi = 3.1415\
926\
535
- 使用内置函数可以赋值给常量
const l = len("hello")
数字常量不需要考虑类型转换问题,但是如果将常量赋值给精度过小的数据变量而导致溢出的情况,编译期会报错。
1). 数字表示
Go语言的常量可以是十进制、八进制或者十六进制的常数
16进制,前缀
0x
或者0X
:0x7ea5
0X0123456789abcdef
8进制,前缀
0
:01234567
0665
10进制:无前缀
-
数字后缀
-
u
或者U
: 无符号 unsigned -
l
或者L
: 长整型 long
-
后缀可以同时使用,顺序不限
3.14
0213
0x4b
0xFeeL
1234UL
2). 转义字符
- 使用反斜杠
\
表示转义字符
3). 赋值
- 常见赋值写法
package main
import "fmt"
func main() {
a := 20
b := a
fmt.Println(b)
b += a
b -= a
b *= a
b /= a
b %= a
b <<= a
b >>= a
b &= a
b ^= a
b |= a
}
- 并行赋值写法
const a, b, c = 1, 2, 3
const (
d, e, f = 4, 5, 6
)
4). 枚举
- 枚举写法
const (
Connected = 0
Disconnected = 1
Unknown = 2
)
- iota关键字
package main
import "fmt"
const (
a = iota // a== 0
b // b == 1 ,隐式调用iota关键字,等同于 b = iota
c // c == 2, 实际等同于 c = iota
d, e, f = iota, iota, iota // 同一行值相同,都是 3,此处不能写一个iota
g = iota // g == 4
h = "h" // h == "h" 但是 iota递增为5
i = h // i == "h" 沿用上方的值,iota递增为6
j = iota // j == 7
k = iota + 50 // 可以参与表达式计算
)
const z = iota // 每个单独定义的常量中,iota会重置为0
func main() {
fmt.Println(a, b, c, d, e, f, g, h, i, j, k, z)
// 0 1 2 3 3 3 4 h h 7 58 0
}
三、变量
1). 变量的声明
- 声明格式:
var identifier type
- 单独定义
var a int
- 同种类型多个变量可以定义在一行
var c, d bool
- 整体定义
var (
e, f int
g, h string
)
- 同时赋值
a, c, d, e, f, g, h = 1, true, true, 2, 3, "a", "b"
fmt.Println(a, c, d, e, f, g, h)
- 同时声明和赋值, 静态赋值
var i, j, k int = 1, 2, 3
- 交换变量的值
i, j = j ,i
i, j, k = k ,i, j
- 动态赋值
var a1, b1, c1 = 1, 2, 3
2). 局部变量的声明
- 在 函数体内 声明变量的简写形式
package main
import "fmt"
func main() {
a := 1 // 等同于 var a = 1
fmt.Println(a)
}
Go语言会自动判断类型
- 全局变量的定义不限定位置,可以定义但是不使用,但是局部变量定义后必须使用
package main
import "fmt"
func main() {
fmt.Println(a)
}
var a = 2
- 当变量被声明但没有赋值时,它的值就是定义时指定类型的零值
- int为0
- float为0.0
- bool为false
- string为空字符串
- 指针为nil等
如果变量甚至没有指定类型,那么系统默认它为int型,值为0,所有变量在Go语言中都是需要初始化的。
命名规范:驼峰命名法, 常量全大写
变量的类型可以在运行时实现自动推断
package main
import (
"fmt"
"os"
)
// 获取环境变量中的值
var (
HOME = os.Getenv("HOME")
USER = os.Getenv("USER")
GOROOT = os.Getenv("GOROOT")
)
func main() {
fmt.Println(HOME, USER, GOROOT)
}
3). 匿名变量
- Go语言支持函数返回多个值,但是如果只需要部分值,可以用空标识符
_
接受
package main
import (
"fmt"
)
// 返回值如果没有指定类型,会沿用后方参数定义的类型
func GetClass() (stuNum int, className, headTeacher string) {
return 49, "一班", "李四"
}
func main() {
stuNum, _, _ := GetClass()
fmt.Println(stuNum)
}
4). init 函数
- Go 语言中,除了可以在全局声明中初始化实体,也可以在
init
函数中初始化。 - init函数是一个特殊的函数,它会在包完成初始化后自动执行,执行优先级比main函数高,并且不能手动调用init函数。
- 每一个源文件有且只有一个init函数,初始化过程会根据包的依赖关系按顺序单线程执行。
可以在开始执行程序之前通过这个函数来对数据进行检验与修复,保证程序执行时状态正常
package main
import (
"fmt"
"math"
)
var Pi float64
func init() {
// 在 init 函数中计算Pi的值
Pi = 4 * math.Atan(1)
}
func main() {
DPi := Pi * Pi
fmt.Println(Pi, DPi)
}