Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言
1 | package main |
注释
- 行注释:
// - 块注释:
/**/ - 文档注释:位于
package之前的注释,以及在变量、函数之前的以变量名、函数名开头的注释
godoc 工具可根据文档注释,自动生成文档
变量
使用 var 关键字声明一个变量,类型后置
1 | var a int = 10 |
若变量在声明时未显式初始化,go 会自动赋零值
| 类型 | 零值 |
|---|---|
| 数值类型 | 0 或 0.0 |
| 布尔类型 | false |
| 字符串类型 | “” |
| 引用/复合类型 | nil |
当变量名为
_时,该变量在初始化后会被丢弃
go 支持类型推断
1 | var a = 10 // a为int类型 |
定义多个变量
1 | var ( |
go 支持并行赋值,通常用于接收函数的多返回值
1 | var a, b = 10, 20 |
类型转换
go 不支持隐式类型转换,所有的类型转换都必须是显式的,且必须能够转换成功,否则会引发编译时错误
1 | a := 10.0 |
类型定义
使用 type 关键字可以定义一个类型,一般用于定义结构体或定义一个底层为基本类型的新类型
1 | type MyInt int // 定义了类型MyInt,它的底层为int,可以与int进行类型转换 |
定义多个类型
1 | type ( |
常量
使用 const 关键字定义一个常量,go 中只支持布尔类型、数值类型和字符串的常量,且必须在编译时确定常量值
1 | const a int = 10 |
在 go 中,const 定义多个常量可以实现枚举的效果
1 | const ( |
若某行没有赋值,则沿用上一行的表达式进行赋值
1 | const ( |
go 提供了一个常量计数器 iota,可以很方便的实现枚举定义,它在每个 const 块中的初始值为 0,每次调用时值加 1,结合沿用上一行赋值,枚举定义可实现如下
1 | const ( |
iota 和沿用上一行赋值可以组成更加复杂的情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 const (
a = iota // 0
b // 1
_ // 2,初始化后被丢弃
// 并行赋值
// c = 3 + 1 = 4
// d = 3 + 2 = 5
c, d = iota + 1, iota + 2
// 沿用上一行赋值
// e = iota + 1 = 4 + 1 = 5
// f = iota + 2 = 4 + 2 = 6
e, f
)
函数
使用 func 关键字定义一个函数,函数的基本形式如下
1 | func fun(param1 type1, param2 type2) (ret1 type1, ret2 type2) { |
由于 go 编译器会自动添加分号,因此左大括号
{必须位于行尾
返回值
go 支持多返回值,有以下形式
1 | func fun1() {} // 无返回值,省略括号 |
go 支持命名返回值,即自动初始化返回值的命名变量,无需在函数体中声明
1 | func fun(a int, b int) (c int) { |
有以下形式
1 | func fun1() (a int) {} // 一个命名返回值 |
包与可访问性
每个 go 文件都只属于一个包,在 go 文件的第一条语句使用 package 关键字声明当前 go 文件属于哪个包,每个 go 应用程序都应该包含一个名为 main 的包
使用 import 关键字导入一个包
1 | import "fmt" |
访问级别
go 中只有公有和包私有两个访问级别,当成员使用大驼峰命名时,该成员为公有,当成员使用小驼峰命名时,该成员为包私有
1 | package pack1 |
值类型与引用类型
go 中的 int、float、bool、string 这些基本类型都是值类型,不可变,在赋值时进行拷贝赋值,值类型的值存储在栈中
引用类型用于复杂数据,使用存储在栈上的指针指向存储在堆中的数据,引用类型赋值时拷贝引用
以上模式与 java 基本相同
go 支持指针类型,属于引用类型,可以获取一个变量的指针(内存地址),可以通过指针修改值,但不能进行指针运算
格式化输出
go 中通过 fmt 包实现格式化输出,主要使用以下函数
| 函数 | 功能 |
|---|---|
fmt.Print() |
直接输出参数,参数间无分隔符,末尾无换行 |
fmt.Println() |
输出参数,参数间自动加空格,末尾强制加换行(最常用的基础输出) |
fmt.Printf() |
按自定义格式输出(核心格式化函数),支持格式化动词,末尾无默认换行 |
fmt.Sprintf() |
不直接输出,而是返回格式化后的字符串(可配合前三者间接输出) |
格式化字符串中通过占位符实现格式化
| 占位符 | 说明 | 示例 | 输出 |
|---|---|---|---|
%v |
按值的默认格式输出 | fmt.Printf("%v", 123) |
123 |
%+v |
结构体输出字段名 | fmt.Printf("%+v", user{Name:"Tom"}) |
{Name:Tom} |
%#v |
输出值的 Go 语法表示 | fmt.Printf("%#v", "abc") |
"abc" |
%T |
输出值的类型 | fmt.Printf("%T", 3.14) |
float64 |
%% |
输出百分号本身 | fmt.Printf("%.2f%%", 99.9) |
99.90% |
%d |
十进制整数 | fmt.Printf("%d", 0x10) |
16 |
%b |
二进制整数 | fmt.Printf("%b", 8) |
1000 |
%x |
十六进制(小写) | fmt.Printf("%x", 255) |
ff |
%X |
十六进制(大写) | fmt.Printf("%X", 255) |
FF |
%f |
浮点数,默认 6 位小数 | fmt.Printf("%f", 3.14) |
3.140000 |
%.2f |
浮点数,指定 2 位小数 | fmt.Printf("%.2f", 3.1415) |
3.14 |
%s |
字符串/字节切片 | fmt.Printf("%s", []byte("abc")) |
abc |
%q |
带引号的字符串 | fmt.Printf("%q", "abc") |
"abc" |
%t |
布尔值 | fmt.Printf("%t", true) |
true |
1 | package main |