从0学习Go语言 -- (安装以及基本语法)

190 阅读6分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战

为什么我开始学习Go语言

天生支持并发
很重要的一点是Go语言天生支持并发,或许其他语言写一个并发并不难,例如Java的Thread。 但是深入学习之后会发现里面的细节很多,而且并发编程的八股文一年一个新花样。而却,大多数现代编程语言(如Java,Python等)都来自90年代的单线程环境。虽然一些编程语言的框架在不断地提高多核资源使用效率,例如 Java 的 Netty 等,但仍然需要开发人员花费大量的时间和精力搞懂这些框架的运行原理后才能熟练掌握。而Go语言作为21世纪诞生的语言,从创建之初就是在多核版本下。 Go语言的并发是基于 goroutine 的,goroutine 类似于线程,但并非线程。可以将 goroutine 理解为一种虚拟线程。Go 语言运行时会参与调度 goroutine,并将 goroutine 合理地分配到每个 CPU 中,最大限度地使用CPU性能。开启一个goroutine的消耗非常小(大约2KB的内存),而一个java线程至少需要 1M ,你可以轻松创建数百万个goroutine

goroutine的特点:

  1. goroutine具有可增长的分段堆栈。这意味着它们只在需要时才会使用更多内存。
  2. goroutine的启动时间比线程快。
  3. goroutine原生支持利用channel安全地进行通信。
  4. goroutine共享数据结构时无需使用互斥锁。

GoLand 安装

Golang 环境安装 安装包下载路径 国内地址
go语言官网 image.png

选择对应版本的安装包安装即可

检查是否安装成功

# 使用go version命令即可
wangdeMacBook-Pro:~ wang$ go version
go version go1.15.2 darwin/amd64

查看go 环境 因为go默认的依赖环境是国外地址,所以有些依赖包下载会很慢

go env命令查看go环境

image.png

我这里已经改过GOPROXY了 go代理
修改GOPROXY

$ go env -w GO111MODULE=on 
$ go env -w GOPROXY=https://goproxy.cn,direct

安装GoLand

自行微信搜一搜,比百度还要好用哦

Go语言基本语法

从Hello World 开始

新建go项目 配置GOPROXY 因为之后学习的很多依赖包都是在github上,下载速度很慢 image.png

创建完成之后如下 image.png 新建go文件 选择 Simple Application 会自动生成一个入口函数

image.png 点击main 前面的三角号。运行一下吧

Hello World

Process finished with exit code 0

我们的 Hello World 就ok了

Go语言中的命令行操作

go 语言作为编译型语言,需要先进行编译才可以运行。在命令行中试一下该如何进行go程序的编译和运行

在命令行中cd 到当前程序所在目录
go build 用于测试编译包,主要检查是否会有编译错误,如果是一个可执行文件的源码(即是 main 包),就会在当前目录直接生成一个可执行文件( .exe 文件)。 编译之后在同级目录会生成可执行文件,可直接运行
也可以go run 运行编译并直接运行程序,它会产生一个临时文件(但实际不存在,也不会生成 .exe 文件),直接在命令行输出程序执行结果,方便用户调试。运行速度也相应较慢

wangdeMacBook-Pro:01_helloword wang$ go build main.go 
wangdeMacBook-Pro:01_helloword wang$ ./main
Hello World!

wangdeMacBook-Pro:01_helloword wang$ go run main.go 
Hello World!

配置GoLand

勾选Reformat code 在保存时会自动格式化代码 image.png

go语言中的常量和变量

变量和常量是编程中必不可少的部分,也是很好理解的一部分。

标识符

在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符由字母数字和_(下划线)组成,并且只能以字母和_开头。 举几个例子:abc__123a123。(大部分语言的标识符都是这样规定的)

关键字 关键字是指编程语言中预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名。 Go语言的关键字有下面这些,不用背下来,之后的学习慢慢就会记住了

    break        default      func         interface    select
    case         defer        go           map          struct
    chan         else         goto         package      switch
    const        fallthrough  if           range        type
    continue     for          import       return       var

未使用的保留字(类似于关键字)

 Constants:    true  false  iota  nil

        Types:    int  int8  int16  int32  int64  
                  uint  uint8  uint16  uint32  uint64  uintptr
                  float32  float64  complex128  complex64
                  bool  byte  rune  string  error

    Functions:   make  len  cap  new  append  copy  close  delete
                 complex  real  imag
                 panic  recover

变量

参考代码

标准声明

Go语言的变量声明格式为:

var 变量名 变量类型

变量声明以关键字var开头,变量类型放在变量的后面,行尾无需分号。 举个例子:

var name string
var age int

批量声明

一次声明多个 变量

var (
    a string
    b int
    c bool
    d float32
)

变量的初始化 Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil。对于string 类型的初始化为 空字符串 所以需要用%q进行格式化

var 变量名 类型 = 表达式

var hobby string = "唱歌"

也可以一次初始化多个变量

var height, university = 175, "清华大学隔壁八百公里外"

类型自动推导,当没有执行类型的时候,go语言会自动根据值来推断当前变量类型

var hobby = "唱歌"

image.png

短变量声明(推荐) 在函数内部,可以使用更简略的 := 方式声明并初始化变量。 注意 :函数内部声明的变量必须使用,否则会编译错误

a := 100
fmt.Println(a)

匿名变量 上面我们说了函数声明则必须使用,那么假如我们一个函数返回了两个值,该怎么办呢

func main() {
   x, _ := doubleReturn()
   fmt.Println(x)
}
func doubleReturn() (x, y int) {
   return 1, 2
}

这时就用到了匿名变量(anonymous variable) _ ,它更像是一个占位符。 匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。

注意事项:

  1. 函数外的每个语句都必须以关键字开始(var、const、func等)
  2. :=不能使用在函数外。
  3. _多用于占位,表示忽略值。

常量

常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var换成了const,常量在定义的时候必须赋值。例如 PI = 3.1415926, KB = 1024等

标准声明

const PI = 3.1415926
const E = 2.71828

批量声明

const (
   pi = 3.1415926
   e = 2.71828
)

在批量声明时,如果没有初始化值,则和上面的值一样,此时的 a,b 都为 2.71828

const (
   pi = 3.1415926
   e  = 2.71828
   a
   b
)

常量计数器 iota

iota在const关键字出现时将被重置为0。const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。

const (
   n1 = iota //0
   n2        //1
   n3        //2
   n4        //3
)

使用_ 跳过某些值

const (
   m1 = iota //0
   m2        //1
   _
   m4 //3
)

插队

const (
   k1 = iota //0
   k2 = 100  //100
   k3 = iota //2
   k4        //3
)
const k5 = iota //0

多个iota定义在一行

const (
   l1, l2 = iota + 1, iota + 2 //1,2
   l3, l4                      //2,3
   l5, l6                      //3,4
)

最常用的位运算

const (
   b  = 1 << (10 * iota)
   kb
   mb
   gb
   tb
   pb 
)

总结

这些就是这篇文章的所有,相关的代码会在github