1 学习前提介绍
语言使用常见命令与操作解释
cd 改变当前工作目录("Change Directory"的缩写)
dir dir是一个常用的命令,用于在命令行界面(如Windows的命令提示符或PowerShell)中列出当前目录中的文件和文件夹。(英文全称是"directory",它是"目录"的缩写)
./ 当前目录
/ 下一子目录
../ 父级目录
e: c: d: 切换盘符
cd / 切换到根目录
ls list进行文件的展示
go run main.go(对应go代码文件) 进行命令行的Go代码运行 //前提是添加好了go.exe的环境变量
go build 对某个项目进行构建编译,形成可执行文件.exe 与go run一样仅对可执行文件
go build -o 其他文件名.exe 形成其他名字的可执行文件
go install 编译项目,对main生成的可执行文件,放置在父文件夹的bin文件中,生成.exe文件
对包文件(内放函数)生成.a文件(静态库文件),放在父文件夹的pkg文件中
(`go install` 是 Go 语言提供的一个命令行工具,用于构建并安装可执行文件或库文件。
当你运行 `go install` 命令时,它会编译你的代码,并将生成的可执行文件或库文件安装到 Go 工 作区的 `bin` 目录或 `pkg` 目录中,具体取决于你的代码是可执行程序还是库。
如果你的代码是一个可执行程序,`go install` 会将编译后的程序安装到 Go 工作区的 `bin` 目录 中。你可以在命令行中直接运行该可执行文件。
如果你的代码是一个库文件,`go install` 会将编译后的库安装到 Go 工作区的 `pkg` 目录中。其 他项目可以通过导入该库来使用它。
在运行 `go install` 命令之前,需要确保你的代码可以成功编译并通过构建。在代码的根目录中运行 go build` 命令可以验证代码是否可以正确构建,如果成功构建,则可以继续运行 `go install` 命 令进行安装。
安装的文件将被放置在 `$GOPATH` 或 `$GOBIN` 环境变量指定的目录中。如果你没有设置这些环境 变量,它们的默认值分别是 `$HOME/go` 和 `$GOPATH/bin`。
使用 `go install` 命令可以方便地构建和安装你的 Go 代码,并使其可被其他项目引用和运行。)
即可以生成包文件,供其他项目进行调用,也可以生成可执行文件,用来让用户使用
一般进入到项目处,再执行该命令,也可以进入到项目的父级目录中在命令尾处加上项目名
go run 运行项目代码,内部会先编译并将编译后的文件放在系统的临时目录,然后再自动执行
go build 运行项目代码,手动编译并生成一个可执行文件,然后自动执行
go install 生成可执行代码+包文件,并且会将编译后的文件放在bin/pkg目录
go run:该命令用于直接运行一个 Go 源代码文件(.go 文件)。它会在临时目录中编译和执行代码,不会生成可执行文件。这对于临时测试和执行简单的程序很有用。
go build:该命令用于编译 Go 程序,并生成一个可执行文件。它会将指定的源代码文件编译为二进制文件,并将可执行文件放在当前目录中。如果没有指定输出文件名,默认会使用源文件的文件名(去除扩展名)作为可执行文件名。
go install:该命令用于编译 Go 程序,并将可执行文件安装到工作空间($GOPATH/bin)或 Go 安装路径中。它会先将代码编译为二进制文件,然后将可执行文件复制到指定的目标路径中。这个命令常用于将可执行文件安装到系统路径中,以便可以在任何地方执行该程序。
go build 主要用于生成可执行文件,并放置在当前目录下,而 go install 则是将可执行文件安装到系统路径中,方便在终端中直接运行
综上所述,go run 用于临时运行代码,go build 用于编译生成可执行文件,go install 用于编译生成可执行文件并安装到系统路径中。
go version 查看版本信息
-bin 编译后的可执行文件
-pkg 编译后的包文件
-src 项目代码
环境变量
GOROOT go编译器安装目录
GOPATH 用于存放的编译后的可执行文件 编译后的包文件 项目代码 (go 1.11版本后,go mod功能,可以不用放在GOPATH)
GOBIN 编译后的可执行文件存放位置
环境搭建
编译器语言:c,c++,go,java 全文翻译(全写完,再去编译翻译)
解释器语言:Python,php,javascript,ruby 实时翻译(写一句翻译一句)
-
开发工具选择
- IDE的全称是集成开发环境(Integrated Development Environment)
- Goland(IDE,是专属Go的开发工具,拥有相应齐全的功能库)
- Vscode(拥有较多的第三方库,本身没有功能)
初识包管理
关于包管理的总结:
-
一个文件夹可以称为一个包
-
在文件夹(包)中可以创建多个文件
-
在同一个包下的每一个文件中必须指定包名称且相同
- 包的名称 package :xx 最好是与父文件夹(包)名字一样
- 如果不一样,也可以,但要求每一个子文件都相同,一般要求一样,除了main
重点:关于包的分类
-
package main
- main包中,必须写一个main函数,此函数是项目的入口(main主函数)
- 有main包且有main函数,编译生成会得到一个可执行文件.否则生成的是包文件
-
非main包
- 用来将代码进行分类,一个大功能一个包
- 同一个包中的文件,可以之间相互调用函数
-
在进行编译运行的时候,可以选择编译的种类
- 文件 仅编译运行单文件
- 包 运行该文件的父级包下的所有文件
- 目录 对应路径下的全部文件都会进行编译
-
同一包下的文件之间的调用
-
归属于同一个包,那么可以直接调用,编译执行时设置成,编译整个包即可
-
归属于同一个祖父包,但不同的父级包,那么可以通过导入对应的包即可
-
-GrandFather -father -baidu.go -google.go -main -main.go 在该.go代码中调用baidu.go方法应该要导包 import"GrandFather/father" father.baidu() father.google() -city.go - 包管理中的命名,如果方法名首字母大写,则认为是可以共用的public,而小写则认为无法共用,为private
-
-
2 特性知识介绍
GO语言简介
-
Golang的称呼是由于Go语言在注册站点地址使用时,其域名go已被注册,故只能改成go language取合并就是golang了,golang只是一个网站域名,标签,语言称呼为go语言,也可以理解为golang只是go语言的另一个称呼
-
谷歌出品的一门高级语言
-
在计算机科学中,脚本一词最早用于描述一类逐行解释和执行的计算机程序。它们不需要编译成机器码,而是由解释器按照语法规则一行一行地解释和执行。
-
脚本语言的概念在上世纪60年代末开始出现。最早的脚本语言之一是Unix操作系统中的Shell脚本语言,它允许用户编写一系列的命令,用于自动化和批处理任务。
随着计算机应用的发展,脚本逐渐成为一种常见的编程方式。它们通常具有简单易学的语法,可以快速编写和调试,以及自动化一些重复性的任务。脚本语言的发展也为网页交互、系统管理、自动化测试等方面提供了便利。
因此,脚本一词在计算机领域中被广泛使用,用于描述这种解释执行的编程方式,即将一系列指令按照特定规则组织起来,通过解释器逐行执行的计算机程序。
一些常见的脚本语言包括Shell脚本、Python、JavaScript、Ruby、Perl等。
-
特点
- 高性能,高并发
- 语法简单,学习曲线平缓
- 丰富的标准库(减少第三方库的使用)
- 完善的工具链
- 静态链接
- 快速编译,几乎拥有最快编译速度的语言
- 跨平台
- 垃圾回收
-
使用公司
-
字节跳动,腾讯,美团,滴滴,百度,谷歌,facebook,哔哩哔哩等均为使用,字节跳动全面拥化go语言
-
字节跳动背景
- 最初使用python,由于性能问题转化为go
- c++不适合在线Web服务
- 早期团队非java背景
- go的性能更好,部署简单,内部RPC,HTTP框架的推广
-
3 基础语法
3.1 从Hello world走进Go语言
如果说有什么是一个程序员上手一门新语言的重要一环,那一定是用新语言输出Hello,world无疑了。那么,今天就让我们从这个新语言入门标志出发,开始我们Go语言的学习之旅。
打印Hello,world的Go语言代码如下:
package main
import {
"fmt"
}
func main(){
fmt.Println("Hello,world")
}
这是Go语言中较为简单的一类代码。但麻雀虽小,五脏俱全。先看第一行package,顾名而思义,肯定指的就是一种包,具体而言,当然就是我们这里的main包了。实际上在Go语言中,package就是其源代码的一个集合,像os、io,以及后面的fmt都是这样的一个包。那么它在使用时有哪些注意事项呢?
- 使用main包时,即为使用应用程序的入口包,编译后会得到一个可执行文件,至于其他的包则没有这个效果
- 可以自定义包,看作是一个存放.go文件的文件夹,该文件夹下所有go文件都要在第一行添加
import {
"fmt"
}
再看第二行,我们用到了import,这就又牵涉到包的另一种操作,包的导入。这是为了在文件中引用其他包的内容,这里就有点像我们c语言中的include添加头文件的用法。
最后就是我们代码的主题部分:在main函数中调用fmt包中的输出函数Println,实现对Hello,world的打印。
简单总结下:为了使程序可执行,我们在一开始声明了main包,然后为了使用标准输出函数,我们又导入了fmt包,最后调用fmt中的Println,实现打印Hello,world。顺带提一句,如果要实现程序的运行,只需要在命令行里输入go run 文件地址,即可。
3.2 变量
//两种声明变量的方式
var a ="Hello,world"//或者var a string ="Hello,world"
a:="Hello,world"
package main //属于main包的一部分(程序的入口文件)
import(
"fmt" // fmt包为格式化字符串,在屏幕输出字符串
)
func main(){
fmt.Println("hello world")
}
从以上两种方式可以看出,Go语言作为一门高级语言,具有自动推导类型的功能,因此,也就不必写出具体变量类型,但如果要写,应注意类型名在变量名后。另外一个细节,在前面没有var时,赋值所用为":=",而非"="
3.3 语句
-
对整个文件进行格式化:
Ctrl + Alt + L -
在 Go 语言中,
var f = float32(e)和f := float32(e)是有细微差别的。var f = float32(e)是一种使用var关键字声明变量并赋值的语法。它会显式地声明一个类型为float32的变量f,并将e的值转换为float32类型进行赋值。f := float32(e)是一种使用短变量声明语法声明变量并赋值的方式。它会根据e的值及其类型自动推断f的类型,并将e的值转换为float32类型进行赋值。
在大多数情况下,这两种语法是等效的,它们都将
e的值转换为float32类型并赋给f。然而,这两种语法在某些特殊场景下有一些微妙的差别。例如,
:=的短变量声明语法只能在函数内部使用,而var关键字可以在函数内外使用。另外,:=还可以用于声明多个变量,而var关键字则需要每个变量单独声明。综上所述,虽然
var f = float32(e)和f := float32(e)在大多数情况下是等效的,但在一些特定场景下可能存在细微的差别。 -
if else
if else 与c++中基本相似 不同于 if 7%2==0{ }else{ } if 后面的判断不需要(),若写了(),编译器在代码保存时会自动去掉,然后要紧跟{} -
循环
-
go中没有while,do-while循环,拥有的是for循环 其结构与c++中也相似,同样也不需要()来包裹限制条件 for j:=1;j<7;j++{ } for{ } 什么都不写代表死循环 for i<=3{ }只留下界限条件也可以
-
-
switch分支结构
-
switch a (无需括号){ case 1: 语句体 case 2: 语句体 default: } 注意的是,go中无需break语句,一旦case选中直接跳出 甚至于无需条件语句,switch用来替换ifelse语句 switch{ case t.Hour()<12: ... default : .... }
-
-
在Go语言中,分号是可选的,因为Go编译器会根据换行符来判断语句的结束。换行符会被视为语句的结束符,不需要使用分号来显式表示语句的终止。,使用换行符来隐式表示语句的结束是Go语言编程的常规做法。
-
然而,如果你希望在一行中写多个语句,可以使用分号将它们分隔开,例如:
fmt.Println("Hello"); fmt.Println("World")
-
-
python是通过缩进来控制语句归属关系的,通过分行符来控制语句的结束
- c语言通过{}来控制语句归属关系,通过分号;来控制语句结束
- go语言结合二者通过{}来控制语句归属关系,通过分行符来控制语句结束
3.4 数组与切片
数组和c语言中的类似,只需要记住它在Go语言中的类型是[n]+元素类型
而切片是一类可变长度的数组,常见操作如下:
//声明和赋值
s := make([]string,5)
s[0] = "a"
//追加
s = append(s,"g")
-
数组定义
-
静态数组,长度固定 var a [5]int len(a) 读取长度 a[4] 正常索引 var two[2][3]int 二维数组 直接定义 b := [5]int{1,2,3,4,5} fmt.Println(b) 直接打印数组全部 fmt.Println(变量,常量,...)可以在一行内打印,以空格隔开
-
-
切片(动态数组)
-
s:=make([]string,3) //创建字符切片,大小容量为3 s[0]="a" s = append(s,"d","e"...) 方法 c :=make([]string,len(s)) make方法创建新切片 copy(c,s) copy方法进行切片复制,后者向前者 fmt.Println(s[2:5]) 输出s[2]-s[5] fmt.Println(s[:5]) 输出到s[5] fmt.Println(s[2:]) 从s[2]开始输出 good := []string{"g","o","o","d"} 不用make方法创建而是直接定义切片
-
3.5 map(字典\哈希\键值对)
就是其他语言中的字典,重点在于key和value的对应,以下是它的常见操作:
m := make(map[int]string)
m[1] = "one"
fmt.Println(r,ok)//r是一个value,此处用于表示判断r是否在m中
delete(m,1)
m :=make(map[string]int) 用make方法进行创建map
m["one"]=1
m["two"]=2
fmt.Println(m) //map[one:1 two:2]
fmt,Println(len(m)) //2
fmt.Println(m["one"]) //1
fmt.Println(m["unknow"]) //0 未有的键所给的值默认为0
r,ok :=m["unknow"] //利用ok 布尔变量来获取其是否存在,是则true,否则false r来获取键所对应的值
delete(m,"one") delete方法来删除
m2 := map[string]int{"one":1,"two":2}
var m2 = map[string]int{"one":1,"two":2}
3.6 range关键字的快速遍历
nums := []int{2,3,4}
sum :=0
for i,num :=range nums{ //遍历的时候是i代表索引,num代表数值,
sum+=num
if num==2{
fmt.Println("index:",i,"num:",num)//index: 0 num: 2
}
}
m := map[string]string{"a":"A","b":"B"}
for k,v :=range m{ //map则遍历键值对
fmt.println(k,v) //b B; a A
}
for k :=range m{
fmt.Println(k) // a b 如果只是一个则为键 如果不需要可以通过_来忽略
}
3.7 函数与指针的使用
函数的基本使用与举例
用func 方法来创建函数
func add(a,b int)int{
return a+b
}
func add1(a int,b int)int{
return a+b
} //可分别定义,也可一起定义
func exists(m map[string]string,k string)(v string,ok,bool){
v,ok=m[k]
return v,ok //go中可以进行多值返回操作,且业务中一般返回多值,第一个为需求值,第二个为错误信息,反馈信息
}
func main(){
res:=add(1,2)
fmt.Println(res)
v,ok :=exists(map[string]string{"a":"A"},"a")
fmt.Println(v,ok)
}
go语言中习惯将变量类型写在后面
指针的基本使用与举例
func add2(n int){
n+=2
}
func add2ptr(n *int){
*n+=2
}
与c语言中类似,用int来定义指针,就是的顺序在类型的前面,而c中为 int * n 可以理解为go的定义与c中的对称,正好前后相反 同样是&取地址