go语言实战(goModules/API/gorm/gin)

一、GoModules项目管理

新建一个项目,如果想把它交给GoModules管理,需要在项目目录下运行命令行并输入:

go mod init

go语言依赖管理:go.mod文件,go mod相关命令。
golang自动下载所有依赖(包括goland怎么设置)
golang自动下载所有依赖最好用的一个命令
go get -d -v ./… (下载全部依赖,经测试好用。)

1、拉取别人开发的项目到本地如何跑:

重要:为什么找不到依赖?
解决:命令行中:
go mod init 项目名//生成go.mod文件
go mod tidy//下载全部依赖的命令
go run main.go//运行main.go之前也会下载全部依赖

如果还是下载不了,检查代理是否配置好:
在这里插入图片描述
GOPROXY=https://goproxy.cn,direct

另外,如果go.mod还有飘红,但文件夹里有,可以不用理了,可能是系统或IDE问题。
在这里插入图片描述

2、自己新建一个项目,包如何管理

gopath已经过时了,现在都用go module + git的形式管理包。
步骤:
1、在github或gitee上新建仓库,初始化一个readme.md
2、把项目拉取到本地。
3、新建两个文件夹,注意规则:每个文件夹内只允许有一个package。
4、两个文件夹内分别新建文件,其中一个为main.go,调用另一个包的文件。
5、go mod init 项目名
项目名和git路径对应上
如 git@gitee.com:sealseadog/my-block-chain01.git
项目名为:gitee.com/sealseadog/my-block-chain01
6、导包时,import “项目名/包名”
如:import “gitee.com/sealseadog/my-block-chain01/chain”

二、go常用的核心API

0、builtin

go语言的关键字只有25个:

package import
var const type struct func interface map
go chan
if else for range break return continue 
select switch case fallthrough  default   
defer
goto 

除关键字之外,不导包就直接能用的方法和类型是预定义标识符。
这些标识符在builtin包中。如:

int float32 bool string 
byte//可存字符 
rune//存更大的字符
true false iota//定义枚举常量
new() make()//区别是什么?
close() cap() len() append() copy() print() delete()//见名知意
panic() recover()

1、time

time.Sleep(1 * time.Second)//延时等待1秒
//如果不是1,而是一个变量或常量,则需要类型转换time.Duaration()
time.Sleep(time.Second * time.Duaration(testTime))
ping := time.Now().Sub(pingStart)//计算与pingStart的差值

2、strings

strings.Repeat(str,3)//将str字符串重复3遍
var strs []string = []string{"hello", "world", "haha"}
join := strings.Join(strs, ";")
//将字符串切片组成一个字符串,以";"隔开
fmt.Println(join)

3、encoding/json

package main//golang study中的demo:

import (
	"encoding/json"
	"fmt"
)

type Movie struct {
	Title  string   `json:"title"`
	Year   int      `json:"year"`
	Price  int      `json:"rmb"`
	Actors []string `json:"actors"`
}

func main() {
	movie := Movie{"喜剧之王", 2000, 10, []string{"xingye", "zhangbozhi"}}

	//编码的过程  结构体---> json
	jsonStr, err := json.Marshal(movie)
	if err != nil {
		fmt.Println("json marshal error", err)
		return
	}

	fmt.Printf("jsonStr = %s\n", jsonStr)

	//解码的过程 jsonstr ---> 结构体
	//jsonStr = {"title":"喜剧之王","year":2000,"rmb":10,"actors":["xingye","zhangbozhi"]}
	myMovie := Movie{}
	err = json.Unmarshal(jsonStr, &myMovie)
	if err != nil {
		fmt.Println("json unmarshal error ", err)
		return
	}

	fmt.Printf("%v\n", myMovie)
}

Lotus代码中的示例:

//把自定义结构体转换成json:注意字段首字母应大写才可访问到。
b, err := json.MarshalIndent(&stores.LocalStorageMeta{
					ID:       stores.ID(uuid.New().String()),
					Weight:   10,
					CanSeal:  true,
					CanStore: true,
				}, "", "  ")
//把json字符串转换成结构体对象
err := json.Unmarshal(b, &psm)

4、reflect

package main
import (
	"fmt"
	"reflect"
)
//主要用两个方法:TypeOf()得到对象的类型,ValueOf()得到对象的值。
func reflectNum(arg interface{}) {
	fmt.Println("type : ", reflect.TypeOf(arg))
	fmt.Println("value : ", reflect.ValueOf(arg))
}
func main() {
	var num float64 = 1.2345
	var num2 int64 = 51
	reflectNum(num)
	reflectNum(num2)
}

5、net和net/http

http包包含http客户端和服务端的实现,利用Get,Head,Post,以及PostForm实现HTTP或者HTTPS的请求.

当客户端使用完response body后必须使用close对其进行关闭.如下所示

resp, err := http.Get("http://example.com/")
if err != nil {
    // handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

6、os,io和io/ioutil,path和path/filepath

os库包含了常用的系统级别调用的操作。
io库定义了读和写等方法。

package main
import (
	"fmt"
	"io"
	"os"
)
func main() {//golangStudy示范os.OpenFile()和io.Writer的用法
	//tty: pair<type:*os.File, value:"/dev/tty"文件描述符>
	tty, err := os.OpenFile("D:/lee/show.txt", os.O_RDWR, 0)
	if err != nil {//         ↑↑↑从该路径读取文件
		fmt.Println("open file error", err)
		return
	}
	//r: pair<type:  , value:>
	var r io.Reader
	//r: pair<type:*os.File, value:"/dev/tty"文件描述符>
	r = tty
	//w: pair<type:  , value:>
	var w io.Writer
	//w: pair<type:*os.File, value:"/dev/tty"文件描述符>
	w = r.(io.Writer)//↓↓↓向该txt文件写入内容
	w.Write([]byte("HELLO THIS is A TEST!!!\n"))
}

os包从环境中读取配置

os.Getenv("LOTUS_DEV")

os包设置环境变量

err := os.Setenv("BELLMAN_NO_GPU", "true")

7、context

7.1 context简单理解:

主要用于在协程之间传递上下文信息,如:
1、取消信号
2、超时信号
3、截止时间信号
4、传递key-value值

7.2 最简单的应用:传递key-value值

package main

import (
	"context"
	"fmt"
	"time"
)

func g2(ctx context.Context) {
	fmt.Println(ctx.Value("third"))
	fmt.Println("第四、周期永远在。")
}
func g(ctx context.Context) {
	fmt.Println(ctx.Value("first"))
	fmt.Println("第二,分析周期")
	go g2(context.WithValue(ctx, "third", "第三,应对周期有三个要点"))
}
func main() {

	ctx := context.WithValue(context.Background(), "first", "第一,认识周期,")
	go g(ctx)
	time.Sleep(time.Second)
}

周期

7.3、取消信号

取消信号传递过来之后,还得自己去解决,进行取消操作才能退出协程。

package main//简单示例
import (
	"context"
	"log"
	"time"
)
func main() {
	ctx, cancel := context.WithCancel(context.Background())
	//返回值cancel是个函数,可以用来结束goroutine
	go g1(ctx)
	for i := 0; i < 10; i++ {
		log.Println("count = ", i)
		if i >= 3 {
			cancel() //取消
		}
		time.Sleep(time.Second)
	}
}

func g1(ctx context.Context) {
	select {
	case <-ctx.Done():
		log.Println("g1取消了")
		return
	}
}
package main//展示goroutine无限套娃情况下的cancel()
import (
	"context"
	"log"
	"time"
)
func main() {
	ctx, cancel := context.WithCancel(context.Background())
	go g1(ctx)
	for i := 0; i < 10; i++ {
		log.Println("count = ", i)
		if i >= 3 {
			cancel() //取消
		}
		time.Sleep(time.Second)
	}
}

func g1(ctx context.Context) {
	go g2(ctx)//调用,套娃
	select {
	case <-ctx.Done():
		log.Println("g1取消了")
		return
	}
}
func g2(ctx context.Context) {
	select {
	case <-ctx.Done():
		log.Println("g2取消了")
		return
	}

}

7.4、取消和超时信号同时使用

package main
import (
	"context"
	"log"
	"time"
)
const testTime int = 6 //测试超时的情况
//const testTime int = 3 //测试手动取消的情况
func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
	go g1(ctx)
	for i := 0; i < 10; i++ {
		log.Println("count = ", i)
		if i >= testTime {
			log.Println("手动取消")
			cancel() //取消
		}
		time.Sleep(time.Second)
	}
}

func g1(ctx context.Context) {
	done := make(chan struct{}, 1) //写1防止内存泄漏
	go func() {
		time.Sleep(time.Second * time.Duration(testTime))
		done <- struct{}{}
	}()
	select {
	case <-ctx.Done():
		log.Println("g1被取消或超时了")
		return
	case <-done: //正常执行完成
		log.Println("g1正常执行完成")
		return
	}
}

8、runtime

尽管 Go 编译器产生的是本地可执行代码,这些代码仍旧运行在 Go 的 runtime(这部分的代码可以在 runtime 包中找到)当中。这个 runtime 类似 Java 和 .NET 语言所用到的虚拟机,它负责管理包括内存分配、垃圾回收、栈处理、goroutine、channel、切片(slice)、map 和反射(reflection)等等。

9、sync

自旋锁和互斥锁的区别
详解go中的混合锁 - mutex

type fundedAddress struct {
//...
	lk    sync.RWMutex
//...
}

func (a *fundedAddress) getReserved() abi.TokenAmount {
	a.lk.RLock()//禁止写入,不禁止读取对应Lock()是禁止读写。
	defer a.lk.RUnlock()//释放锁
	return a.state.AmtReserved
}

三、go持久层框架gorm

简介:gorm是中国的golang开发者jinzhu开发的持久层框架,目前最新版本是v2版。

v1版的依赖:

"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"

v2版的依赖:

"gorm.io/driver/mysql"
"gorm.io/gorm"

gorm v2官方文档中文版

四、Web框架Gin

Gin框架中文文档

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值