go语言标准库地址:Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国
go安装
国内下载地址:Go下载 - Go语言中文网 - Golang中文社区
下载最新版本,这里我下载 https://studygolang.com/dl/golang/go1.20.2.windows-amd64.msi
安装好后,打开cmd,输入go version可以查看go的版本信息
go配置环境变量
右击此电脑–>属性–>高级系统设置–>环境变量
GOROOT D:\Program Files\Go
GOPATH D:\go
用户变量也添加GOPATH。
GOPATH D:\go
go env 配置
最后还有一些go的env变量需要配置:
GO111MODULE:包管理模式,auto即可,可以同时使用MODULE和GOPATH模式(非mod项目也可以build 解决 go: go.mod file not found in current directory or any parent directory)。
GOPROXY:配置包代理镜像,使用国内的镜像源代替
GONOPROXY/GONOSUMDB:配置私有模块,公司内根据需要配置
打开cmd,尝试阶段配置前两个即可
go env -w GO111MODULE=auto
go env -w GOPROXY=https://goproxy.cn,direct
#公司内根据需要配置
go env -w GONOPROXY=xxx.xxx
go env -w GONOSUMDB=xxx.xxx
vscode扩展go
把D:\Program Files\Go目录下文件都拷贝到在d:\go工作目录下
在D:\go\src\hello\目录下
编写go第一个程序main.go
package main
import "fmt"
func main() {
fmt.Println("helle world go")
}
cmd,执行go run main.go
打印 hello word go,项目运行成功
go开发目录
go语言特点
- 自动立即回收
- 更丰富的内置类型
- 函数多返回值
- 错误处理
- 匿名函数和闭包
- 类型和接口
- 并发编程
- 反射
- 语言交互性
1.go没有命名空间概念,只有包package,引用的包名比较简短import “fmt”
2.go没有class类的概念,只有type name struct{} 结构体,结构体只属性没有方法
3.go中但凡声明或引用都要使用,不使用会报错,go中检查比较严谨
go的关键词
go的保留字
go语言定义
go语言作用域
GO中的fmt-向外输出
GO中的fmt-获取输入
GO中的fmt-中printf占位符
GO中的fmt-中printf占位符
GO中的fmt-中printf占位符
GO中的fmt-中printf占位符
go语言运算符
go中包分类
go中import和package
go中init和main
init相当于一个构造函数,针对go的包而显示的
作用:是用来初始化变量、参数等
1.init 可以定义多个 main只能是一个
2.init执行顺序:
1)根据引入的包的顺序执行init
2)在包目录下.go中的init加载是根据文件名的顺序执行
3)一个文件中有多个init时,从上向下加载顺序执行
先是引入包->加载常量->加载变量->加载init方法->最后加载main
练习:
GO中的指针
区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针。
& : 取地址
* : 根据地址取值
当一个指针被定义后没有分配到任何变量时,它的值为 nil
var p *string
fmt.Println(p)
fmt.Printf("p的值是%v\n", p)
var kh string = "0"
fmt.Println("&kh",&kh) 0xc0003a1f0
f := &kh
*f = "p"
fmt.Println(*f) p
fmt.Println(kh) p
fmt.Println(f) 0xc0003a1f0
fmt.Println(&f) 0xc00006030
流程控制
如果:if-else
选择:Switch
循环:for
结束与跳过:break - continue
跳转:goto
变量
常量
数据类型
数据类型
数据类型-整数类型
数据类型-布尔类型
数据类型-浮点类型
数据类型-字符串类型
数据类型-字段常用函数
数据类型-byte和rune类型
数据类型-强转strconv
单元测试
dao.go
package model
func getUserByName(name string) string {
return "用户信息"+name
}
单元测试
dao_test.go
package moel
import "testing"
func TestGetUserByName(t *testing.T) {
fmt.Println(getUserByName("yzz"))
}
进入model目录cmd测试
go test
数组定义 == 一维数组
var arr0 [5]int = [5]int{1, 2, 3}
var arr1 = [5]int{1, 2, 3, 4, 5}
var arr2 = [...]int{1, 2, 3, 4, 5, 6}
var str = [5]string{3: "hello world", 4: "tom"}
d := [...]struct {
name string
age uint8
}{
{"user1", 10}, // 可省略元素类型。
{"user2", 20}, // 别忘了最后一行的逗号。
}
数组定义 == 多维数组
全局
var arr0 [5][3]int
var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
局部:
a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."。
数组定义相关函数
len -- 来求长度,比如string、array、slice、map、channel ,返回长度
var usernames [5]string = [5]string{"shineyork", "cara"}
fmt.Println(len(usernames))
切片
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大
切片 特点
切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。
切片的长度可以改变,因此,切片是一个可变的数组。
切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。
cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。
切片的定义:var 变量名 []类型,比如 var str []string var arr []int。
如果 slice == nil,那么 len、cap 结果都等于 0。
切片定义
var identifier []type 为 nil
var slice1 []type = make([]type, len) 或 slice1 := make([]type, len)
arr1 := []int{0, 2}
数组与切片操作
切片操作
切片之[:]
切片之make
Cap重新分配规律
s := make([]int, 0, 1)
c := cap(s)
for i := 0; i < 50; i++ {
s = append(s, i)
if n := cap(s); n > c {
fmt.Printf("cap: %d -> %d\n", c, n)
c = n
}
}
Map集合
// 定义map集合
var goClassMap map[string]string
goClassMap = make(map[string]string)
// 或
// goClassMap := make(map[string]string)
// 添加数据
goClassMap["teacher"] = "yzz"
goClassMap["contents"] = "go"
fmt.Println(goClassMap)
练习
package main
import "fmt"
var (
k string
i int
)
const (
c = "qwe"
l = 10
)
type ih interface { //定义接口
}
func init() {
// fmt.Println("main")
}
func init() {
// fmt.Println("main1")
}
const (
n = iota
p = 100
q = iota
s
)
// 数组全局定义
var arr1 [5]int = [5]int{0, 1, 2, 3, 4}
var arr2 = [...]int{0, 1, 2, 3, 4, 5}
var arr3 [5][3]int
var arr4 [2][3]int = [...][3]int{{1, 2, 3}, {4, 5, 6}}
// 切片全局定义
var sar1 []int = []int{0, 1, 2, 3, 4}
// map集合
var map1 map[string]string
func main() {
map1 = make(map[string]string)
map1["class"] = "go"
map1["content"] = "go content"
fmt.Println(map1)
//map值是切片
map2 := make(map[string][]string, 0)
s := make([]string, 0)
s = append(s, "a", "b", "c")
map2["k"] = s
fmt.Println(map2)
//切片类型map值是map
map3 := make([]map[string]string, 2)
map3[0] = map1
map3[1] = make(map[string]string, 0)
map3[1]["class"] = "php"
map3[1]["content"] = "php is the best language"
fmt.Println(map3)
for key, val := range map3 {
fmt.Println(key, val)
}
//打印数组
// fmt.Println(arr1[2:3])
// fmt.Println(arr2[:3])
// fmt.Println(arr2[3:])
// fmt.Println(arr3)
// fmt.Println(arr4)
// // 数组局部定义
// arr5 := [2][3]int{{1, 2, 3}, {4, 5, 6}}
// arr6 := [...][3]int{{1, 2, 3}, {4, 5, 6}}
// fmt.Println(arr5)
// fmt.Println(arr6)
//打印切片
// fmt.Println(sar1)
// sar1 = append(sar1, 5)
// fmt.Println(sar1)
// sar2 := make([]int, 2)
// sar2[0] = 1
// sar2[1] = 2
// sar2 = append(sar2, 3)
// fmt.Println(sar2)
// fmt.Println(len(sar2), cap(sar2))
// sar2 = append(sar2, 4, 5, 6, 7, 8, 9, 10, 11)
// fmt.Println(sar2)
// fmt.Println(len(sar2), cap(sar2))
// sar2 = append(sar2, 6, 7, 8, 9)
// fmt.Println(sar2)
// fmt.Println(len(sar2), cap(sar2))
//sum1 := "1"
//a, err := strconv.ParseInt(sum1, 10, 64)
//if err != nil {
// fmt.Println(err)
// }
// fmt.Println(a)
// b, _ := strconv.ParseInt(sum1, 10, 64)
// fmt.Println(b)
//fmt.Println(Itoa(a))
//fmt.Println(n)
//fmt.Println(q)
//fmt.Println(s)
/*
t := srm.User{ //对结构体赋值
Name: "yzz",
Age: 18,
Sex: 1,
}
fmt.Println(t.GetAge())
fmt.Println(t.ToString())
*/
//var k string = "123"
//k = "asdf"
//fmt.Println(k)
//fmt.Println(c)
//srm.Index()
}