小白go环境搭建与基础语法

374 阅读5分钟

官网下载安装程序

golang.google.cn/dl/

vscode插件安装

然后 f1 执行 go install update tools

image.png

代理配置

七牛代理不限速

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` ,自动识别typeint

_(下划线)是个特殊的变量名,任何赋予它的值都会被丢弃

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
  • 整数类型  intuint
  • 浮点类型 float32float64
  • 复数 complex128complex64
  • 字符串 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)
}

框架热部署

github.com/cosmtrek/ai…

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