官网下载安装程序
vscode插件安装
然后 f1 执行 go install update tools
代理配置
七牛代理不限速
go env -w GOPROXY=https://goproxy.cn,direct
docker环境开发go
docker run -dit -v /d/goenv:/root/goenv golang
1.用vscode连接到远程的项目
2.在docker环境中在下载go插件
3.配置代理
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
4.工作区另存为桌面
数据定义
常量、变量
1.定义常量
const constantName = value
2.定义变量
var variableName type //定义一个名称为“variableName”,类型为"type"的变量
如果在方法内部可以简化声明 ,使用 :=
a:=1 // 相当于 var a int = 1
:= 这个符号取代`var`和`type` ,自动识别type为int
_(下划线)是个特殊的变量名,任何赋予它的值都会被丢弃
array、slice(切片)、map(字典)
1.array(数组):
b := [5]int{1, 2, 3, 4, 5}
2.slice(动态数组):
是一个引用类型,指针指向一个底层数组,通过`array[i:j]`来获取
其中`i`是数组的开始位置,`j`是结束位置
slice := array[2:4]
也可以初始化一个可增长的动态数组
s := make([]int,0) //初始化切片
s = append(s,1) //添加1个元素
3.map(字典): 格式为 `map[keyType]valueType`
// 初始化一个字典
rating := map[string]float32{"C":5, "Go":4.5, "Python":4.5, "C++":2 }
// map有两个返回值,第一个返回值为key对应的value。
第二个返回值,如果不存在key,那么ok为false,如果存在ok为true
csharpRating, ok := rating["C#"]
那么go中数据的 type 有几种
bool布尔类型true,false. 默认false- 整数类型
int和uint - 浮点类型
float32和float64 - 复数
complex128和complex64 - 字符串
string - error类型
流程和函数
1.if ,switch (逻辑处理)
if x > 10 {
fmt.Println("x is greater than 10")
} else {
fmt.Println("x is less than 10")
}
switch sExpr {
case expr1:
some instructions
case expr2:
some other instructions
case expr3:
some other instructions
default:
other code
}
2.for (遍历数据)
for index:=0; index < 10 ; index++ {
sum := 0;
sum += index
}
模拟while写法
for sum < 1000 {
sum += sum
}
遍历map字典,for+range
for k,v := range map{
fmt.Println("map's key:", k)
fmt.Println("map's val:", v)
}
go是多返回值,如果key不使用,用 _ 代替,否则会编译错误
for _,v := range map{
fmt.Println("map's val:", v)
}
支持`break`和`continue`关键字
3.函数
关键字func用来声明一个函数
//go语言支持多返回值
//返回 A+B 和 A*B
func SumAndProduct(A, B int) (int, int) {
return A+B, A*B
}
// 不定参数
func myfunc(arg ...int) {}
值得一提的是go中约定 小写的func是私有的,大写的func是公有的
func main(){} //私有的
func Main(){} //公有的
面向对象
如果说java是一切皆对象 ,那么go可以说一切皆类型
1.封装
type Rectangle struct {
width, height float64
}
func area(r Rectangle) float64 {
return r.width*r.height
}
2.继承
属性方法继承
type Human struct {
name string
age int
phone string
}
type Student struct {
Human //匿名字段
school string
}
type Employee struct {
Human //匿名字段
company string
}
// 在human上面定义了一个method
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}
方法重写
//Human定义method
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
//Employee的method重写Human的method
func (e *Employee) SayHi() {
fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
e.company, e.phone) //Yes you can split into 2 lines here.
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}
3.多态
取决于接受者的不同(func与方法名直接定义接受者)
func main() {
rec := Rectangle{10.0,10.0}
fmt.Println(rec.area())
}
type Rectangle struct {
width, height float64
}
type Circle struct {
radius float64
}
func (r Rectangle) area() float64 {
return r.width*r.height
}
func (c Circle) area() float64 {
return c.radius * c.radius
}
测试
一般用test结尾进行创建一个文件。如json_test.go
package main
import (
"encoding/json"
"fmt"
"testing"
)
type Blog struct {
BlogId string `json:"blogId"`
Title string `json:"title"`
Content string `json:"content"`
Uid int32 `json:"uid"`
State int32 `json:"state"`
}
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Email string `json:"email,omitempty"` // 使用omitempty选项表示当字段为空时不在JSON中输出
}
func TestJsonDecode(t *testing.T) {
str := `{"title": "some title","Uid":1}`
var data Blog
err := json.Unmarshal([]byte(str), &data)
if err != nil {
t.Errorf("Error during JSON unmarshalling: %v", err)
return
}
fmt.Println(data)
}
func TestJsonEncode(t *testing.T) {
// 创建一个Person实例
p := Person{
Name: "张三",
Age: 25,
Email: "",
}
jsonBytes, _ := json.Marshal(p)
jsonString := string(jsonBytes)
fmt.Println(jsonString)
}
框架热部署
go install github.com/cosmtrek/air@latest
air运行项目
dlv调试项目
打包
可执行文件
go build -ldflags "-w -s" .
upx近一步压缩打包程序大小
https://github.com/upx/upx/releases
打包内容到exe内部
package main
import (
"embed"
"fmt"
)
// 嵌入一整个文件夹,作为embed.FS类型
//go:embed resource
var embedDir embed.FS
func main() {
// 读取嵌入的文件
a, _ := embedDir.ReadFile("resource/a.txt")
fmt.Println(string(a))
c, _ := embedDir.ReadFile("resource/dir/c.txt")
fmt.Println(string(c))
}
注意 //go:embed resource 不是注释而是一个语法,加此标识就会识别resources下面的映射目录
docker打包
dockerfile文件
# 第一阶段:构建应用
FROM golang:bullseye AS builder
# 设置容器工作目录在 /app
WORKDIR /app
# 将本地的代码文件复制到容器中的工作目录, COPY . ./app 可以用点替代工作目录的意思
COPY . .
# 设置代理地址来加快下载依赖的速度
RUN go env -w GOPROXY=https://goproxy.cn,direct
# 下载依赖
RUN go mod download
# 编译应用
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o main .
# 第二阶段:制作干净的生产镜像
FROM alpine:latest
# https依赖
RUN apk --no-cache add ca-certificates
WORKDIR /app
# 从builder阶段产物中获取main可执行程序
COPY --from=builder /app/main .
# 将时区设置为东八区
RUN echo "https://mirrors.aliyun.com/alpine/v3.8/main/" > /etc/apk/repositories \
&& echo "https://mirrors.aliyun.com/alpine/v3.8/community/" >> /etc/apk/repositories \
&& apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo Asia/Shanghai > /etc/timezone \
&& apk del tzdata
# 挂载目录
# VOLUME ["/go/kingProject/config","/go/kingProject/log"]
# 执行命令
CMD ["./main"]
# 暴露端口
EXPOSE 8083