Skip to content

第一章 Golang入门基础 v1.0

第一部分 Golang简介

一、优点

  1. 极其简单的部署方式(可直接编译成机器码,不依赖其他库,直接运行即可部署)
  2. 静态类型语言(编译时可以检查出隐藏的大多问题)
  3. 语言层面的并发(天生基因支持,充分利用多核)
  4. 强大的标准库(runtime系统调度机制,高效GC垃圾回收,丰富标准库)
  5. 简单易学(25个关键字,内嵌C语法支持,面向对象特征、跨平台)

二、缺点

  1. 包管理:大部分第三方库在github上
  2. 所有的Excepiton都用Error来处理
  3. 对C的降级处理,并非无缝

三、主要领域

  1. 云计算基础设施(docker、K8s、etcd、consul、cloudflare等)
  2. 基础后端软件(tidb、influxdb、cockroachdb等)
  3. 微服务(go-kit、micro等)
  4. 互联网基础设施(以太坊、hyperledger)

第二部分 Golang基本使用

一、基础组成

  • 包声明(源文件中非注释的第一行指明这个文件属于哪个包,main表示一个可独立执行的程序)
  • 引入包
  • 函数、变量、语句&表达式、注释(//单行注释 与 /多行注释/)

二、构建程序

构建程序命令:go build 文件名

三、访问属性

当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected)

四、注意要点

  1. 字符'{'不能单独放在一行(区别于C++)
  2. 文件名与包名没有直接关系,不一定要将文件名与包名定成同一个。
  3. 文件夹名与包名没有直接关系,并非需要一致。
  4. 同一个文件夹下的文件只能有一个包名,否则编译报错

五、代码规范

1.变量

命名规范: 简洁明了,一般使用小驼峰命名,如:theElement

注意要点

  • 缩略词全大写,当位于变量开头且不需导出时,使用全小写,例如使用ServeHTTP而不是ServeHttp,使用XMLHTTPRequest或者xmlHTTPRequest
  • 变量距离使用地方越远,需携带越多上下文信息;全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义

2.函数

命名规范:函数名尽量简短,使用大驼峰命名,如:FindElement

注意要点

  • 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的
  • 当名为foo的包某个函数返回类型Foo时,可以省略类型信息而不导致歧义
  • 当名为foo的包某个函数返回类型T时(T并不是Foo),可以在函数名中加入类型信息

3.软件包

命名规范只由小写字母组成,不包含大写字母和下划线等字符

  • 简短并包含一定的上下文信息。例如schematask 等。
  • 不要与标准库同名。例如不要使用sync或者strings

注意要点

  • 尽量不使用常用变量名作为包名。例如使用bufio而不是 buf
  • 尽量使用单数而不是复数。例如使用encoding而不是encodings
  • 谨慎使用缩写。例如使用fmt在不破坏上下文的情况下比format更加简短

第三部分 基础语法

一、格式化输出(fmt.Printf)与格式化字符串(fmt.Sprintf)

格式:

go
fmt.Sprintf(格式化样式, 参数列表…)  # 格式化字符串并返回结果
fmt.Printf(格式化样式, 参数列表…)   # 格式化输出到标准输出
[格式化符号]
格式描述格式描述
%v按值的本来值输出%+v按值的本来值输出并展开
%#v输出Go语法格式的值%T输出Go语法格式的类型和值
%%输出%本体%b整型以二进制方式显示
%o整型以八进制方式显示%x整型以十六进制方式显示
%X整型以十六进制大写方式显示%d整型以十进制方式显示
%UUnicode 字符%f浮点数
%p指针,十六进制方式显示%s字符串格式

二、变量

1.变量声明

go
var 变量名 [显式指定数据类型] = 变量值  //方式1
变量名 := 变量值  //方式2

2.基本类型

  1. 数字类型
    • 整数类型
      • 有符号整数:int8, int16, int32, int64, int
      • 无符号整数:uint8, uint16, uint32, uint64, uint
      • 特殊类型:uintptr(用于存储指针的无符号整数类型)
    • 浮点数类型
      • float32, float64
    • 复数类型
      • complex64, complex128
  2. 布尔类型(bool):值可以是 truefalse
  3. 字符串类型(string):用于存储字符串。

3.数组

go
var 数组名 [数组大小]指定数据类型
go
数组名[索引]

4.切片

在Golang中,切片相当于可变长度的数组,在GoLang中常使用切片以规避数组必须定义长度的缺点。

go
变量名 := make([]指定数据类型, n, size)      // 创建初始长度为n、容量为size的一个切片
变量名 := []指定数据类型{数值1, 数值2, ...}   // 直接以{}中的数值列表生成切片
var 变量名 []指定数据类型                    // 定义一个指定数据类型的切片
go
// 类似Python
s := [5]int{1, 2, 3, 4, 5}
arr1 := s[2:5]     // 可以从数组中生成切片,此操作取得切片s的第3到第5个值返回其副本
arr2 := arr1[0:2]  // 从切片arr1生成一个新的切片arr2,包含arr1的第1到第2个元素
[常用方法]
方法作用
len(s)获取切片s的当前长度
cap(s)获取切片s的当前容量
append(s, el1, el2, ...)在切片s的末尾添加新数值,返回新切片
copy(copyS, originS)将originS的内容复制到copyS切片中

5.映射(字典)

go
m := map[索引类型]变量值类型{索引值1: 变量值1, 索引值2: 变量值2, ...}
m := make(map[索引类型]变量值类型, size)  // 创建一个初始容量为size的map
go
m := map[string]int{"one": 1, "two": 2}
value, exists := m["three"]
if exists {
    fmt.Println("Key exists with value:", value)
} else {
    fmt.Println("Key does not exist")
}
[常用方法]
方法作用
len(m)获取字典m的当前长度
delete(m, k)删除键为k的键值对