GOGo学习之路
FANSEAGo学习之路
环境安装
Windows上安装 Go 环境并配置环境变量 (超详细教程)_go环境变量配置 windows-CSDN博客
【2024最新】GoLand最新版本免费使用教程附带安装包!超详细_哔哩哔哩_bilibili
| 12
 3
 
 | GoLand 破解网盘链接:https://tool.nineya.com/s/1iduahtej
 提取码:q23b
 
 | 
语法学习
https://chat.deepseek.com/a/chat/s/f93445e7-f6fc-42e0-824b-2a76b9ee7c17
标准结构
| 12
 3
 4
 5
 6
 7
 
 | package main  
 import "fmt"
 
 func main() {
 fmt.Println("Hello, World!")
 }
 
 | 
变量声明
type:
- int- 存储整数(整数),例如 123 或 -123
- float32- 存储浮点数,带小数,例如 19.99 或 -19.99
- string- 存储文本,例如”Hello World”。 字符串值用双引号括起来
- bool- 存储具有两种状态的值:真或假
| 1
 | var variablename type = value
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | var name string = "Go"
 
 var count = 10
 
 count := 5
 
 const
 (
 pi = 3.14
 pi1 = 3.15
 )
 
 const
 (
 pi = iota
 pi1
 )
 
 var x,y,z = 1,2,3
 g,h:= "g","h"
 
 | 
TIP:var count = 10 和count := 5的区别是什么
第一个可以声明在函数之外、第二个只能声明在函数内部使用,而且必须初始化
Pair对
static type:基本数据类型
concrete type:interface指向的具体数据类型
一种变量的type是只能是以上两者的一个

pair类型会在赋值之后连续传递
在这里allType万能类型的type其实是concrete type,并且是指向a的type的,为string

子父接口继承,正是因为pair的机制,使其支持自下而上转换
复合类型
数组:
| 12
 
 | var arr [3]int = [3]int{1,2,3}arr1 := [3]int{1,2,3}
 
 | 
动态数组:
| 12
 3
 
 | slice := []int{1, 2, 3}slice = append(slice,4)
 fmt.Println(slice[3])
 
 | 
Map映射:
| 12
 
 | m := map[string]int{"one":1,"two":2}value, exists := m["three"]
 
 | 
结构体
type struct_name struct {
 member1 datatype;
 member2 datatype;
 member3 datatype;
 …
}
| 12
 3
 4
 
 | type Person struct{Name string
 Age int
 }
 
 | 
| 12
 3
 4
 
 | func main(){p :=Person{Name:"xiaoming",Age:123}
 fmt.Println(p.Name)
 }
 
 | 
| 12
 3
 4
 5
 
 | func main(){var p Person
 p.Name = "xiaoming"
 fmt.Println(p.Name)
 }
 
 | 
以下包含了结构体方法定义、结构体修改的操作
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | type Rectangle struct {Width, Height float64
 }
 
 
 func (r Rectangle) Area() float64 {
 return r.Width * r.Height
 }
 
 
 
 func (r *Rectangle) Scale(factor float64) {
 
 r.Width *= factor
 r.Height *= factor
 }
 
 func main(){
 
 rect := Rectangle{Width: 3, Height: 4}
 fmt.Println(rect.Area())
 rect.Scale(2)
 fmt.Println(rect.Area())
 
 }
 
 | 
继承:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 
 | package main
 import "fmt"
 
 type Human struct {
 name string
 sex  int
 }
 
 func (h *Human) Detail() {
 fmt.Println("name:", h.name, "sex:", h.sex)
 }
 func (h *Human) Sex(s int) {
 h.sex = s
 }
 
 type SuperMan struct {
 Human
 level int
 }
 
 func (sh SuperMan) Fly() {
 fmt.Println("superMan fly")
 }
 
 func main() {
 h := Human{name: "tiancai", sex: 1}
 h.Sex(0)
 sh := SuperMan{Human{name: "spiderMan", sex: 1}, 10}
 h.Detail()
 sh.Detail()
 sh.Fly()
 }
 
 | 
| 12
 3
 
 | name: tiancai sex: 0name: spiderMan sex: 1
 superMan fly
 
 | 
接口
type interface_name interface{
	function_name type
}
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | type Rectangle struct {Width, Height float64
 }
 
 
 func (r Rectangle) Area() float64 {
 return r.Width * r.Height
 }
 
 type Shape interface{
 Area() float64;
 }
 func printx(s Shape){
 fmt.Println(s.Area())
 }
 
 
 rect := Rectangle{Width: 3, Height: 4}
 printArea(rect)
 
 | 
空接口:
interface{},Go中所有的变量都继承于这个,可以理解为java的Object类,使用该关键字可以在方法中引入不限制类型的变量
他同时提供了类型断言的方法,来判断类型:arg.(string)判断是否是字符串类型
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | func typeJudge(i interface{}) {switch i.(type) {
 case Human:
 fmt.Println("Human")
 case SuperMan:
 fmt.Println("SuperMan")
 default:
 fmt.Println("unknow")
 }
 }
 
 | 
函数定义
无返回值:
func FunctionName(param1 type, param2 type)  {
 // 要执行的代码
}
| 12
 3
 
 | func print1(name string){fmt.Println("print:",name);
 }
 
 | 
有返回值:
func FunctionName(param1 type, param2 type) type {
 // 要执行的代码
 return output
}
| 12
 3
 
 | func add(i int)int{return i+1
 }
 
 | 
多返回值:
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | func divide(a, b int) (int, error) {if b == 0 {
 return 0, errors.New("division by zero")
 }
 return a / b, nil
 }
 
 i,_:=divide(1,0)
 print1(i)
 
 | 
可变参数:
这里的_代表当前元素的索引不存储,相当于一个空位置
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | func main(){print1(sum(1,2,3))
 }
 
 func sum(nums ...int)int{
 total :=0
 for _,num := range nums{
 total +=num
 }
 return total
 }
 
 
 | 
函数作为参数:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | func main(){
 i :=apply(op,1,2)
 print1(i)
 }
 
 
 func apply(op func(int, int) int, a, b int) int {
 return op(a, b)
 }
 func op(a,b int)int{
 return a+b
 }
 
 | 
递归调用:
| 12
 3
 4
 5
 6
 7
 
 | func test(count int) int{if(count >= 10){
 return 0
 }
 fmt.Println(count)
 return test(count+1)
 }
 
 | 
控制结构
条件语句:
相比java就是省去了括号
| 12
 3
 4
 5
 6
 7
 
 | if count>0{return count
 }else if count == 0{
 return 0
 }else{
 return -1
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | if v:=compute();v>0{
 fmt.Println(v)
 }else{
 fmt.Println(0)
 }
 
 func compute() int{
 return 0
 }
 
 | 
循环语句:
| 12
 3
 4
 5
 6
 7
 8
 
 | for i:=1;i<=5;i++{print1(i)
 }
 
 for{
 print1("123")
 
 }
 
 | 
while循环:
| 12
 3
 4
 5
 
 | v :=5for v>0{
 print1(v)
 v--
 }
 
 | 
range循环:
类似于java的foreach
| 12
 3
 4
 
 | nums := []int{1, 2, 3}for i,v := range nums{
 fmt.Printf("index:%d,value:%d\n",i,v)
 }
 
 | 
| 12
 3
 
 | index:0,value:1index:1,value:2
 index:2,value:3
 
 | 
指针

如果*p=a,那么p=&a
*p表示的是p地址指向的内存,而&a表示的是a内存的地址

值交换:
| 12
 3
 4
 5
 
 | func Exchange(a, b *int) {a1 := *a
 *a = *b
 *b = a1
 }
 
 | 
其他关键字
defer:
在程序结束之后进行操作
defer晚于return执行
多个defer最下面的先执行

项目结构
go执行流程

Go Moduels
结构:

指令:
| 命令 | 作用 | 类比 Java | 
| go mod init [module-path] | 初始化一个新的 Go 模块,生成 go.mod 文件 | 类似于创建 Maven 项目 / 初始化 pom.xml | 
| go get [package]@[version] | 手动获取某个依赖包(可指定版本) | 类似于在 pom.xml 添加依赖,或使用 mvn install | 
| go mod tidy | 清理未使用的依赖,添加缺失的依赖 | 类似于 Maven 的依赖分析,清理未使用的 jar | 
| go list -m all | 查看当前模块依赖的所有第三方包 | 类似于查看 Maven 依赖树 | 
| go mod vendor(可选) | 将依赖复制到项目下的 vendor 目录(类似传统打包方式) | 类似 Maven 的 mvn dependency:copy-dependencies到 lib/ | 
| go build / go run | 编译或运行程序,自动解析依赖 |  | 
如何手动引入依赖?
直接在代码里 import "xxx",然后运行 go run/main/build,Go 会自动下载依赖
包工作流程
初始化modules:
| 1
 | go mod init github.com/fansea0/my-go-project # github.com/fansea0/my-go-project 是模块名称
 | 
创建目录结构:
| 12
 3
 4
 5
 6
 
 | go_modules_test/├── go.mod  # 保存该模块外部依赖信息(类似于外链),外部依赖通常会保存在gopath的lib包下
 ├── main.go # 程序主入口,包名为main
 └── lib/
 ├── lib1.go # 模块子包的类,lib1与lib2的package需要一致,同一个子包的类型可以直接调用
 └── lib2.go
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | module github.com/fansea0/my-go-project
 
 go 1.24.5
 
 require rsc.io/quote v0.0.0-20190312145912-0406d7298882
 
 require (
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
 rsc.io/sampler v1.3.0
 )
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | package main
 
 import (
 "fmt"
 "rsc.io/quote"
 
 "github.com/fansea0/my-go-project/lib"
 )
 
 func main() {
 fmt.Println(quote.Hello())
 lib.Test()
 lib.Test2()
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | package lib
 
 import "fmt"
 
 func init() {
 fmt.Println("lib1 init")
 }
 
 func Test() {
 fmt.Println("lib1 test")
 }
 
 | 
| 12
 3
 4
 5
 6
 
 | package lib
 
 func Test2() {
 Test()
 }
 
 | 
| 12
 3
 4
 5
 
 | lib1 init
 Hello, world.
 lib1 test
 lib1 test
 
 | 
匿名包:
包引入之后必须要使用,否则不能通过编译,这里提供匿名包,允许包不使用,但是依然会执行包的init方法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | package main
 import (
 "fmt"
 "rsc.io/quote"
 
 _ "github.com/fansea0/my-go-project/lib"
 )
 
 func main() {
 fmt.Println(quote.Hello())
 
 }
 
 | 
GoPATH是什么
GOPATH 是 Go 语言在 1.11 版本之前 管理项目、依赖和代码工作空间的核心机制
用于依赖管理,提供打包功能的工作空间集成,在go Modules出现之后被淘汰
并发编程