1. 简介
Go语言是Google出品的一门通用的计算机编程语言
特点
-
高性能、高并发
有和C++、Java媲美的性能
内置对高并发的支持,其他编程语言以库的形式支持。在GoLang中不需要像其他语言一样去寻找经过高度性能优化的第三方库来开发应用,只需要使用标准库,或基于标准库的第三方库即可开发高并发应用程序
-
语法简单,学习曲线平缓
Go语言语法风格类似于C语言,并且在C语言的基础上进行了大幅度的简化:
-
吃掉了不必要的表达式括号
-
只有for循环一种表示方法,就可以实现数值、键值等遍历
-
实现简单的Http服务器
package main import { ”net/http“ } func main() { http.Handle("") } -
-
丰富的标准库
Go语言和Python一样,拥有及其丰富,功能完善,质量可靠的标准库。很多情况下,不需要借助第三方库就可以完成大部分基础功能的开发。大大降低了学习和使用成本
最关键的是,标准库有很高的稳定性和兼容性保障,还能持续享受语言迭代所带来的性能优化,这时第三方库所不具备的。
-
完善的工具链
Go语言在诞生指出,就有着丰富的工具链
不论是编译,代码格式化,错误检查,帮助文档,包管理还有代码补充提示,这些都有对应的工具
Go语言还完整内置了单元测试框架,能够支持单元测试,性能测试,代码覆盖率,数值竞争检测,这是保证代码正缺稳定运行的必备利器
-
静态链接
在Go语言内所有的编译结果默认都是静态链接的,只需要拷贝唯一一个可执行的文件,不需要添加任何东西就可以部署运行。在线上容器环境运行,镜像体积可以控制的非常小,部署非常方便快捷。像C++需要附加一堆.source,才可以正确运行,如果不正确的话就会崩溃;java需要附加一个庞大的JRE才可以运行
-
快速编译
Go语言有静态语言里几乎最快的编译速度。在字节跳动,大量的微服务,在线上部署之前的编译小于1min。在真正本地开发的时候,几乎任何时候修改完一套代码都能够在1s种左右,增量编译完成。这个速度对于C++开发者来说几乎不可想象
-
跨平台
Go语言可以在常见的Windows、Linux、MaxOS的操作系统中运行
也能够用来开发安卓、IOS软件
Go可以在各种设备上运行,包括:路由器、树莓派
Go语言还有很方便的交叉编译特性,能够轻易的在笔记本上编译出二进制拷贝到路由器上运行,还不需要配置交叉编译环境
-
垃圾回收
Go是一门带垃圾回收的语言,与Java类似
写代码的时候,不需要考虑内存的分配释放,可以专注于业务逻辑
基础语法&标准库
-
Hello World
package main // 代表这个文件属于main包的一部分。main包是程序的入口包,也就是程序的入口文件 import ( "fmt" // 导入了标准库种的format包,这个包是用来往屏幕输入输出字符串、格式化字符串 ) // main函数 func main() { fmt.Println("hello world Cug") } // go run 运行 // go build 编译 -
变量(var)
Go是一门强类型语言,每一个变量都有自己的变量类型
常见的变量类型:
- 字符串
- 整数
- 浮点型
- 布尔型
Go语言中字符串是内置类型,可以直接通过“+”号拼接
也可以用“=”号去比较两个字符串
Go中大部分运算符的使用和优先级都和C/C++类似
变量声明
Go中,变量的声明有两种方式:
-
var 变量名 = 值
这种方式一般会自动推导变量的类型,如果有需要也可以显式的写出变量类型
var b, c int = 1, 2
-
变量名:= 值
var a = "initial" var b, c int = 1, 2 var d = true var e float64 f := float32(e) g := a + "foo" fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0 fmt.Println(g) // initialapple -
常量(const)
Golang的常量没有确定的类型,会根据使用的上下文自动确定类型
const s string = "constant" const h = 500000000 const i = 3e20 / h fmt.Println(s, h, i, math.Sin(h), math.Sin(i)) -
if-else
与C/C++类似,不同点在于:
- if后面没有括号,如果有括号的话,编译器会自动去掉括号
- 后面必须加大括号,不能像C++一样把if语句写在同一行
-
for
Golang中没有while循环、没有do-while循环,只有for循环
最简单的,for后面什么都不写就是死循环,也可以使用经典的C循环
continue(继续循环)、break(跳出循环)同C++
-
switch
与C/C++类似
switch后面的变量名不需要括号
在C++中switch的case不加break会往下执行所有的case分支,Golang中不需要添加,不会跑到其他的分支。
Golang中的switch功能强大,可以使用任意类型的变量。比如字符串、结构体、甚至可以用来取代任意的if-else语句(switch后不加变量,在case内写逻辑分支)
t := time.Now() switch { case t.Hour() < 12: fmt.Println("It's before noon") default: fmt.Println("It's after noon") } -
数组
数组是具有编号,且长度固定的元素序列。
创建
var a [5]int:可以存放5个int元素的数组avar twoD [2][3]int:可以存放2行3列的int元素的数组twoD真实环境中很少使用数组,基本上都是使用切片
-
切片(slice)
切片不同于数组,是一种可变长度的数组,可以任意时刻去更改长度,也有更多丰富的操作。
创建
可以通过make来创建一个切片:
s := make([]string,3)操作
根据下标添加元素
s[0] = "a" s[1] = "b" s[2] = "c" fmt.Println("get:", s[2]) // c fmt.Println("len:", len(s)) // 3也可以通过append追加元素(必须把append的结果赋值给原数组),因为Golang中slice原理是:存储了长度+ 容量+ 指向数组的指针。在执行append操作的时候,如果容量不够,会返回一个新的slice,所以需要赋值回去
s = append(s, "d") s = append(s, "e", "f") fmt.Println(s) // [a b c d e f]使用make创建slice的时候可以直接指定长度,这样可以避免频繁的扩容错做
s := make([]string, 3)copy可以在两个slice之间拷贝数据
c := make([]string, len(s)) copy(c, s) fmt.Println(c) // [a b c d e f]slice还拥有像python一样的切片操作:
fmt.Println(s[2:5]) // [c d e](不包括第5个位置的元素) fmt.Println(s[:5]) // [a b c d e](不同于python,不支持负数索引) fmt.Println(s[2:]) // [c d e f]