1 学习方向
Go的全称为:go language,它可以用来做区块链开发、Go服务器端开发、游戏开发、分布式/云计算开发
2 go概述
2.1 Google创造Go语言的原因
(1)解决现有语言不能高效利用硬件资源(多核多CPU)
(2)现有语言风格不统一、计算能力不够高效、处理高并发能力不够
(3)c/c++ 虽然很快,但是编译速度慢,而且存在内存泄漏风险
2.2 go语言的特点
(1)从c语言继承了好多理念,包括表达式语法、控制结构、基础数据结构、调用参数传值、指针等
(2)引入了包的概念,用于组织程序结构,Go语言的一个文件必须属于某个包,不能单独存在
(3)引入了垃圾回收机制
(4)天然的并发支持
① 从语言层面支持并发,实现简单
② goroutine,轻量级线程,可实现高并发处理,高效利用多核
② 基于CSP并发模型实现
(5)引入了管道通信机制(channel),通过channel可以实现不同的goroutine之间的互相通信
(6)支持函数返回多个值, 如下:
func sumAndSub(n1 int, n2 int) (int, int) {
sum := n1 + n2
sub := n1 - n2
return sum, sub
}
(7)切片、延时执行defer等
2.3 Go SDK安装
2.3.1 sdk包下载
SDK地址:https://golang.org/doc/install?download=go1.9.2.windows-amd64.zip
下载直接解压即可完成安装,如安装到c盘,解压会生成一个go文件夹
2.3.2 环境变量配置
GO_HOME = C:\Program Files\go //go的安装目录
PATH = %GO_HOME%\bin
GOPATH = G:\My_Work\learn-project\golang //配置go的工作目录
2.3.3 验证
cmd中执行:go version
2.4 第一个Go程序
2.4.1 源码编写
2.4.2 编译
进入该目录在cmd中执行go build编译go源代码
此时会生成一个go.exe的二进制文件
2.4.3 运行
2.5 Go程序开发的注意事项
(1)Go源码文件以.go为扩展名
(2)Go应用程序的入口为main函数
(3)Go语言严格区分大小写
(4)Go方法由一条条语句构成,每个语句后不需要分号(Go在编译时会在每行后自动加分号)
(5)Go编译器是一行行编译的,因此不要在一行写多条语句,否则报错
(6)Go语言中定义的变量或者import导入的包如果没有被使用到,代码编译错误
(7)大括号成对出现,否则编译不通过
2.6 注释
1)行注释
//注释内容
2)块注释
/*
注释内容
*/
2.7 Go 学习网址
1)官方编程指南:https://tour.go-zh.org/welcome/1
2)GO中文网:https://studygolang.com/
3 Golang变量
3.1 变量的三种使用方式
1)指定变量类型,声明后若不赋值,则使用默认值
func main() { //没有赋值,则使用默认值,int的默认值为0 var i int fmt.Println("i=", i) }
2)根据值自行判断变量类型(类型推导)
func main() { var name = "hello" fmt.Println("name=", name) }
3)省略var ,注意 := 左侧的变量不能为已声明过的,否则会导致编译错误
:= 表示定义并赋值,如name := "tome" 等价于如下两步
var name string
name = "tome"
func main() { name := "tom" fmt.Println("name=", name) }
3.2 一次声明多个局部变量的三种方式
1)方式一
func main() { var n1, n2, n3 = 100, 200, 300 fmt.Println("n1=", n1, "n2=", n2, "n3=", n3) }
2)方式二
func main() { var n1, name, n3 = 100, "tome", 300 fmt.Println("n1=", n1, "name=", name, "n3=", n3) }
3)方式三
func main() { n1, name, n3 := 100, "tome", 300 fmt.Println("n1=", n1, "name=", name, "n3=", n3) }
3.3 全局变量
1)全局变量声明
var n1 = 100 var n2 = 200 var name = "tom" func main() { fmt.Println("n1=", n1, "name=", name, "n2=", n2) }
2)一次声明多个全局变量
var ( n1 = 100 n2 = 200 name = "tom" ) func main() { fmt.Println("n1=", n1, "name=", name, "n2=", n2) }
3.4 变量类型
3.5 整数的各个类型
3.6 整形的使用细节
1)Golang各整数类型分:有符号和无符号,int uint大小与系统有关
2)Golang的整形默认声明为int型
3)如何在程序中查看某个变量的字节大小与数据类型
import ( "fmt" "unsafe" ) func main() { var num = 22 fmt.Printf("num的数据类型为:%T, 占用字节大小为:%d", num, unsafe.Sizeof(num)) }
3.7 浮点型
注:float64的精度要比float32的精度高,所以要保存更高精度的浮点数值用float64
3.7.1 浮点型使用注意细节
1)Golang浮点类型有固定的范围与字段长度,与操作系统无关
2)Golang浮点型默认声明为float64
3)浮点型常量有两种表示形式
- 十进制数形式,如:5.12
- 科学计数法形式,如:5.123e2 相当于5.123 * 10的二次方 其中e也可以大写为E,5.12E-2 表示5.12除以10的二次方
4)通常情况下应该使用更高精度的float64
3.8 字符类型
3.8.1 基本介绍
Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存
注:字符串是由一串固定长度的字符连接起来的字符序列,Go的字符串是由单个字节连接起来的,也就是说传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的
func main() { var num byte = 'a' fmt.Println("num:", num) //输出97 }
tip:
- 如果我们保存的字符在ASCII表中,那么可以直接保存到byte
- 如果我们保存的字符对应的ASCII值大于255,那么可以考虑使用int类型保存
- Go语言的字符统一用UTF-8进行编码,所以在Go中不用担心乱码的问题了
3.9 布尔类型 bool
3.9.1 基本介绍
1)bool类型的值只能为true或false
2)bool类型占用1个字节
3)bool类型适用于逻辑运算
3.10 字符串类型string
3.10.1 基本介绍
Go字符串是由单个字节连接起来的,它使用UTF-8编码
3.10.2 使用注意细节
1)字符串一旦被赋值了,字符串就不能被修改了,在Go中字符串是不可变的,如下
func main() { var str = "hello" //会编译错误 str[0] = 'a' }
但是这种是ok的
func main() { var str = "hello" str = "word" //输出word fmt.Println(str) }
2)字符串的两种表示形式
- 双引号:会识别转义字符
func main() { var str = "hello \r\n word" //输出内容会识别换行符 fmt.Println(str) }
- 反引号:以字符串的原生形式输出,包括换行符与特殊字符,可以实现防止代码攻击,输出源代码等
func main() { var str = ` package main import ( "fmt" ) func main() { fmt.Println("hello word") } ` //将会源码输出为字符串 fmt.Println(str) }
3)字符串拼接
使用+来拼接两个字符串
func main() { var str = "hello" + " word" //输出hello word fmt.Println(str) }
4)当一行字符串太长时,需要使用多行字符串,可以使用如下方式
正确的方式
错误的方式
3.11 基本数据类型的默认值
3.12 基本数据类型的转换
3.12.1 基本介绍
Golang与java/c不同,Go在不同的数据类型之间赋值时需要显示准换,也就是说Golang中数据类型不能自动转换
3.12.2 基本语法
表达式T(v) 将值v准换为类型T,如
func main() { var num int32 = 100 var num2 float32 = float32(num) fmt.Println(num, num2) }
3.12.3 基本类型转string
1)通过fmp.Sprintf来转换(推荐这种方式转换,方便)
2)通过strconv包来转换
3.12.4 string类型转基本类型
使用strconv包进行转化
3.12.5 基本类型与string类型转换注意细节
1)在将string类型转换为基本类型时,要确保string类型能够转换为有效的数据,如可以将"123"转换为一个整数,但是将"hello"转换为整数的话Go中不会报错,它会直接将其转成0。
结论:如果一个string值无法转换为基本类型,那么直接赋值为默认值
3.13 指针
3.13.1 基本介绍
1)基本数据类型,变量存的就是值,也叫值类型
2)获取变量的地址用&,如下
3)指针类型:指针变量存的是地址,这个地址指向的空间才是值
4)获取指针类型所指向的值,如:var po *int,使用*po来获取po所指向的值
3.13.2 指针的使用细节
1)值类型:都有对应的指针类型,形式为 *数据类型 ,如int对应的指针类型为*int,float32对应的指针类型为*float32,以此类推
2)值类型包括:基本数据类型int系列、float系列、bool、string、数组和结构体struct
3.14 值类型与引用类型
3.14.1 值类型与引用类型说明
1)值类型:基本数据类型int系列、float系列、bool、string、数组和结构体struct
2)引用类型:指针、slice切片、map、管道channel、interface
3.14.2 值类型与引用的使用特点
1)值类型:变量直接存储值,内存通常(也有可能通过逃逸分析在堆中分配)在栈中分配
示意图
2)引用类型:变量存储的是一个地址,这个地址对应的空间才是真正存储的(数据)值,内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的空间就会被GC回收
示意图
3)内存的栈区与堆区图
3.15 常量
1)常量使用const修饰
2)常量在定义的时候必须初始化
3)常量定义后不能修改
4)常量只能修饰bool、数值类型(int, float系列)、string类型
5)语法:const 常量名 [type] = value
6)示例
const name = "tom"
const a int = 10
4 预告
好了,本次就介绍到这里,下次将会介绍运算符、流程控制、函数、数组等章节