go笔记 配置go语言的编译环境
此处省略一万字
基础 首先变量的值用var定义,定义的类型和c一样的
声明
第一种
var name type name =value
这里和C不一样的就是C是 type name
第二种
var name =value
第三种
name :=value
注意第三种会自动推变量的类型 这种的好处就是可以不用写变量类型而直接赋值注意这种不能用于全局变量的声明!!!
那么问题来了,”=”和”:=”有什么区别呢?希望各位好好思考一下
同时它也可以一次给多个赋值,和c一样
第一种
var name1,name2 type name1,name2 =value1,value2
第二种
var name1,name2 =value1,value2
第三种
name :=value
ps:定义了的必须要使用,不使用会报错,如果按ctrl+s,则vscode会自动给你把没使用的删掉 这条不仅仅是对变量名有效,对包名,函数什么的都有效
常量 在定义的前面加个const就行了,和c一样
类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 bool false byte 和char一样int int16 , uint16 -32768 ~ 32767 , abs -> 0 ~ 65535 int32 , uint32 -21 亿~ 21 亿, 0 ~ 42 亿int64 , uint64 float32 float64 complex64 complex128 array 数组 struct 结构体string slice 切片 map channel nil 通道 interface nil 接口function nil 函数
对应的格式化打印占位符: 1 2 3 4 5 6 7 8 9 10 %v,根据你的类型输出 %T,打印变量类型 %s,打印字符串 %f,浮点类型 %x,%X,16 进制 %c,打印字符 %p,打印地址 %d,10 进制的整数 %b,2 进制的整数 %o,8 进制
算术运算符
和c一样
/
%
++ 注意go里面没有++i
– 和上面一样
逻辑运算符
位运算符
X
Y
X&Y
X|Y
X^Y
0
0
0
0
0
0
1
0
1
1
1
1
1
1
0
1
0
0
1
1
赋值运算
=
+=
-=
*=
/=
%=
<<= 和 >>=
&=
^=
|=
剩下的就没什么好讲的了 基本和c差不多
依赖管理
依赖管理三要素
配置文件,描述依赖 go.mod
中心仓库管理依赖库 proxy
本地工具 go get/mod
创建的命令为 go mod init projectname.go
依赖配置 依赖配置产生冲突的时候会选择最低的兼容版本
工具-go mod
init 初始化,创建go.mod文件
download 下载模块到本地缓存
tidy 增加需要的依赖,删除不需要的依赖
测试 首先测试很重要!!!!
单元测试–规则
单元测试–覆盖率 定义:代码覆盖 是软件测试中的一种度量手段,是一种白盒测试方法,描述程序中源代码被测试的比例和程度,所得比例就称之为代码覆盖率 。我们在做测试时,代码覆盖率常常被用来作为衡量测试好坏的指标。
我们必须尽可能的提高测试率。
一般覆盖率:50%~60% 较高覆盖率:80%+
测试分支相互独立,全面覆盖
测试单元粒度足够小,函数单一职责
分层结构
数据层:数据model
逻辑层:业务entity
视图层:试图view
并发编程 1.子协程 创建一个协程非常简单,就是在一个任务函数前面添加一个go关键字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package mainimport ( "fmt" "sync" "time" ) func hello (i int ) { fmt.Println("hello world: " + fmt.Sprint(i)) } func test () { for i := 0 ; i < 5 ; i++ { go func (j int ) { hello(j) }(i) } time.Sleep(time.Second) } func main () { test() }
这里我们需要注意的是一定要加time.Sleep(time.Second)
,这是为了开启子协程的时候主协程不立刻退出(延迟两秒)
这里还有的就是他们会互相抢占资源,所以打印的不一定是按照顺序来的
比如这里我打印的就是
1 2 3 4 5 hello world: 1 hello world: 0 hello world: 3 hello world: 4 hello world: 2
2.通道 通道分为有缓冲
和无缓冲
Unbuffered:=make(chan int) 整型无缓冲通道
buffered:=make(chan int ,10) 整形有缓冲通道
无缓冲通道用于执行同步通信,而有缓冲通道用于执行异步通信。
通道可以用这样的图来表示
将值发送到通道德代码块需要用<-
运算符
1 2 src:=make(chan string,5)//创建通道 src<- " hello"//通过通道发送字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mainfunc main () { src := make (chan int ) dest := make (chan int , 3 ) go func () { defer close (src) for i := 0 ; i < 10 ; i++ { src <- i } }() go func () { defer close (dest) for i := range src { dest <- i * i } }() for i := range dest { println (i) } }
通道的发送和接收特性
对于同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的。
发送操作和接收操作中对元素值的处理都是不可分割的。
发送操作在完全完成之前会被阻塞。接收操作也是如此。
3.WaitGroup同步 上面的第一个的代码不是很优雅,所以我们这里使用wait函数实行同步
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package mainimport ( "fmt" "sync" "time" ) func hello (i int ) { fmt.Println("hello world: " + fmt.Sprint(i)) } func ManyGoWait () { var wg sync.WaitGroup wg.Add(5 ) for i := 0 ; i < 5 ; i++ { go func (j int ) { defer wg.Done() hello(j) }(i) } wg.Wait() } func main () { ManyGoWait() }
4.runtime包
runtime.Gosched() 让出等待时间
runtime.Goexit() 退出当前协程
runtime.GOMAXPROCS(num int)设置最大核心数 如果改成1则只有一核执行
mutex 我们接下来先看这段代码
1 2 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 package mainimport ( "fmt" "sync" ) var i int = 100 var wg sync.WaitGroupfunc add () { i += 1 fmt.Printf("i++: %v\n" , i) } func sub () { i -= 1 fmt.Printf("i--: %v\n" , i) } func main () { defer wg.Done() for i := 0 ; i < 100 ; i++ { wg.Add(1 ) go add() go sub() } fmt.Printf("end i: %v\n" , i) }
这里的运行的结果我们会发现有时候不是100,有时候是100。这就是因为异步的原因,那么我们怎么解决呢?
这里我们需要进行加锁
代码如下:
1 2 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 34 35 36 37 38 39 40 package mainimport ( "fmt" "sync" "time" ) var i int = 100 var wg sync.WaitGroupvar lock sync.Mutexfunc add () { defer wg.Done() lock.Lock() i += 1 fmt.Printf("i++: %v\n" , i) time.Sleep(time.Millisecond * 10 ) lock.Unlock() } func sub () { lock.Lock() defer wg.Done() time.Sleep(time.Millisecond * 2 ) i -= 1 fmt.Printf("i--: %v\n" , i) lock.Unlock() } func main () { for i := 0 ; i < 100 ; i++ { wg.Add(1 ) go add() go sub() } wg.Wait() fmt.Printf("end i: %v\n" , i) }
timer
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport ( "fmt" "time" ) func main () { timer := time.NewTicker(time.Second * 2 ) fmt.Printf("time.Now(): %v\n" , time.Now()) t1 := <-timer.C fmt.Printf("t1: %v\n" , t1) }
两者的时间差了两秒
这里也可以不需要用t1接收 也就是说两者等价
1 2 3 4 5 6 7 8 9 10 11 12 13 package mainimport ( "fmt" "time" ) func main () { timer := time.NewTicker(time.Second * 2 ) fmt.Printf("time.Now(): %v\n" , time.Now()) <-timer.C fmt.Printf("time.Now(): %v\n" , time.Now()) }
1 2 3 4 5 6 7 8 9 10 11 12 package mainimport ( "fmt" "time" ) func main () { fmt.Printf("time.Now(): %v\n" , time.Now()) <-time.After(time.Second * 2 ) fmt.Printf("time.Now(): %v\n" , time.Now()) }
上面都等价
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mainimport ( "fmt" "time" ) func main () { timer := time.NewTicker(time.Second * 5 ) timer.Reset(time.Second * 1 ) <-timer.C fmt.Println("after" ) }
ticker定时器 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package mainimport ( "fmt" "time" ) func main () { ticker := time.NewTicker(time.Second) counter := 1 for _ = range ticker.C { fmt.Println("ticker..." ) counter++ if counter > 5 { break } } }
每一秒运行一次,运行五次结束
原子变量 上面的那个还需要上锁,我们把代码改一下
1 2 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 package mainimport ( "fmt" "sync" "sync/atomic" "time" s ) var i int32 = 100 var wg sync.WaitGroupvar lock sync.Mutexfunc add () { atomic.AddInt32(&i, 1 ) } func sub () { atomic.AddInt32(&i, -1 ) } func main () { for i := 0 ; i < 100 ; i++ { go add() go sub() } time.Sleep(time.Second) fmt.Printf("end i: %v\n" , i) }
标准库篇 创建文件 代码如下:会在当前目录下创建一个a.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package mainimport ( "fmt" "os" ) func createFile () { f, err := os.Create("a.txt" ) if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Println("f,name()" , f.Name()) } } func main () { createFile() }
创建目录 代码如下:会在当前目录下创建一个a文件夹
1 2 3 4 5 6 7 func makeDir () { err := os.Mkdir("a" , os.ModePerm) if err != nil { fmt.Printf("err: %v\n" , err) } }
如果想创建多级可以用以下的函数
1 2 3 4 5 6 7 func makeDir () { err2 := os.MkdirAll("a/b/c" , os.ModePerm) if err2 != nil { fmt.Printf("err2: %v\n" , err2) } }
删除文件&目录 代码如下:
1 2 3 4 5 6 func remove () { err := os.Remove("a.txt" ) if err != nil { fmt.Printf("err: %v\n" , err) } }
删除目录的代码如下:
1 2 3 4 5 6 func removeDir () { err := os.RemoveAll("a" ) if err != nil { fmt.Printf("err: %v\n" , err) } }
删除a和a下面的所有的目录
打印当前工作目录 1 2 3 4 5 6 7 8 func wd () { dir, err := os.Getwd() if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Printf("dir: %v\n" , dir) } }
修改当前目录 1 2 3 4 5 6 7 func changeWd () { err := os.Chdir("d:/" ) if err != nil { fmt.Printf("err: %v\n" , err) } fmt.Println(os.Getwd()) }
修改当前目录到D盘
重命名 1 2 3 4 5 6 func Rename () { err := os.Rename("test01.txt" , "test02.txt" ) if err != nil { fmt.Printf("err: %v\n" , err) } }
将test01.txt修改成为test02.txt
这里需要注意的是,我们假设test01.txt里面写的是111,而test02.txt里面的内容是222。执行上面的操作之后,原来的test02.txt将会被覆盖,也是是说test02.txt里面的内容将会变成111 这里需要大家注意一下
读文件 1 2 3 4 5 6 7 8 func readFile () { b, err := os.ReadFile("test.txt" ) if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Printf("b: %v\n" , string (b[:])) } }
写文件 1 2 3 4 5 func writeFile () { s := "hello world" os.WriteFile("test.txt" , []byte (s), os.ModePerm) }
但是这里需要注意的是这里会直接覆盖
打开文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package mainimport ( "fmt" "os" ) func main () { f, err := os.OpenFile("notes.txt" , os.O_RDWR|os.O_CREATE, 0755 ) if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Printf("f: %v\n" , f.Name()) } if err := f.Close(); err != nil { } }
读文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func read () { f, _ := os.Open("notes.txt" ) for { buf := make ([]byte , 10 ) n, err := f.Read(buf) if err == io.EOF { break } fmt.Printf("n: %v\n" , n) fmt.Printf("string(buf): %v\n" , string (buf)) } }
注意:这里可能会产生脏读
1 2 3 4 5 6 7 8 func read () { f, _ := os.Open("a.txt" ) buf := make ([]byte , 3 ) n, _ := f.ReadAt(buf, 4 ) fmt.Printf("n: %v\n" , n) fmt.Printf("string(buf): %v\n" , string (buf)) }
io包 NewReader() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mainimport ( "fmt" "strings" ) func main () { r := strings.NewReader("hello world" ) buf := make ([]byte , 15 ) r.Read(buf) fmt.Printf("string(buf): %v\n" , string (buf)) }
json包 1 2 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 34 35 package mainimport ( "encoding/json" "fmt" ) type Person struct { Name string Age int Email string } func test () { p := Person{ "tom" , 20 , "666@email.com" , } b, _ := json.Marshal(p) fmt.Printf("string(b): %v\n" , string (b)) } func test2 () { b := []byte (`{"Name":"tom","Age":20,"Email":"666@email.com"}` ) var p Person json.Unmarshal(b, &p) fmt.Printf("p: %v\n" , p) } func main () { test2() }
xml包 1 2 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 package mainimport ( "encoding/xml" "fmt" ) type Person struct { Name string Age int Email string } func test () { p := Person{ "tom" , 20 , "666.@email.com" , } b, _ := xml.MarshalIndent(p, " " , " " ) fmt.Printf("string(b): %v\n" , string (b)) } func main () { test() }
结果:
1 2 3 4 5 6 string(b): <Person> <Name>tom</Name> <Age>20</Age> <Email>666.@email.com</Email> </Person>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 func test1 () { s := ` string(b): <Person> <Name>tom</Name> <Age>20</Age> <Email>666.@email.com</Email> </Person> ` b := []byte (s) var p Person xml.Unmarshal(b, &p) fmt.Printf("p: %v\n" , p) }
结果:
1 p: {tom 20 666.@email.com}
mysql篇 安装驱动
go get -u github.com/go-sql-driver/mysql
初始化模块 go mod init m
执行 go mod tidy go mod tidy
导入驱动
import (
“database/sql”
“fmt”
“time”
)
驱动代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package mainimport ( "database/sql" "fmt" "time" _ "github.com/go-sql-driver/mysql" ) func main () { d, err := sql.Open("mysql" , "root:password@/go_db" ) if err != nil { panic (err) } fmt.Printf("d: %v\n" , d) d.SetConnMaxLifetime(time.Minute * 3 ) d.SetMaxOpenConns(10 ) d.SetMaxIdleConns(10 ) }
初始化 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 func initDB () (err error ) { dsn := "root:password@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True" d, err := sql.Open("mysql" , dsn) if err != nil { return err } err = d.Ping() if err != nil { return err } return nil }
crud 插入 1 2 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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package mainimport ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) var db *sql.DBfunc initDB () (err error ) { dsn := "root:1234@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True" d, err := sql.Open("mysql" , dsn) db = d if err != nil { return err } err = d.Ping() if err != nil { return err } return nil } func insert () { s := "insert into user_tbl( username, password) values (?,?) " r, err := db.Exec(s, "lisi" , "ls123" ) fmt.Println("走到这了" ) if err != nil { fmt.Printf("err: %v\n" , err) } else { i, _ := r.LastInsertId() fmt.Printf("i: %v\n" , i) } } func main () { err := initDB() if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Println("初始化成功" ) } insert() }
记录错误 1 2 panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x1 addr=0x20 pc=0x71d0f3]
代码如下:
1 2 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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package mainimport ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) var db *sql.DBfunc initDB () (err error ) { dsn := "root:1234@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True" d, err := sql.Open("mysql" , dsn) if err != nil { return err } err = d.Ping() if err != nil { return err } return nil } func insert () { s := "insert into user_tbl( username, password) values (?,?) " r, err := db.Exec(s) fmt.Println("走到这了" ) if err != nil { fmt.Printf("err: %v\n" , err) } else { i, _ := r.LastInsertId() fmt.Printf("i: %v\n" , i) } } func main () { err := initDB() if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Println("初始化成功" ) } insert() }
原因是因为db没有被赋值,也就是init的第三行,把它解掉注释就好了
查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type User struct { id int username string password string } func query () { s := "select * from user_tbl where id=?" var u User err := db.QueryRow(s, 2 ).Scan(&u.id, &u.username, &u.password) if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Printf("u: %v\n" , u) } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func querymore () { s := "select * from user_tbl" r, err := db.Query(s) var u User defer r.Close() if err != nil { fmt.Printf("err: %v\n" , err) } else { for r.Next() { r.Scan(&u.id, &u.username, &u.password) fmt.Printf("u: %v\n" , u) } } }
更新 1 2 3 4 5 6 7 8 9 10 func update () { s := "update user_tbl set username=?,password=? where id=?" r, err := db.Exec(s, "big kite" , "456789" , 2 ) if err != nil { fmt.Printf("err: %v\n" , err) } else { i, _ := r.RowsAffected() fmt.Printf("i: %v\n" , i) } }
操作MongoDB 下载 下载地址
https://www.mongodb.com/download-center/community
打开客户端
mongo.exe
创建数据库
use go_db;
创建集合
db.createCollection(“student”);
下载驱动
go get go.mongodb.org/mongo-driver/mongo
插入文档
插入一条数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 func insert () { initDb() s1 := Student{ Name: "tom" , Age: 20 , } c := client.Database("go_db" ).Collection("Student" ) ior, err := c.InsertOne(context.TODO(), s1) if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Printf("ior.InsertedID: %v\n" , ior.InsertedID) } }
插入多条
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 func insertMore () { initDb() c := client.Database("go_db" ).Collection("Student" ) s1 := Student{ Name: "tom" , Age: 20 , } s2 := Student{ Name: "rose" , Age: 20 , } stus := []interface {}{s1, s2} imr, err := c.InsertMany(context.TODO(), stus) if err != nil { fmt.Printf("err: %v\n" , err) } else { fmt.Printf("imr.InsertedIDs: %v\n" , imr.InsertedIDs) } }
到mongod里面查找数据是
db.Student.find()
查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 func find () { initDb() ctx := context.TODO() defer client.Disconnect(context.TODO()) c := client.Database("go_db" ).Collection("Student" ) c2, err := c.Find(ctx, bson.D{}) if err != nil { log.Fatal(err) } defer c2.Close(ctx) for c2.Next(ctx) { var res bson.D c2.Decode(&res) fmt.Printf("res: %v\n" , res) fmt.Printf("res.Map(): %v\n" , res.Map()) } }
更新 1 2 3 4 5 6 7 8 9 10 11 12 func update () { initDb() c := client.Database("go_db" ).Collection("Student" ) ctx := context.TODO() update := bson.D{{"$set" , bson.D{{"name" , "big kite" }, {"age" , 22 }}}} ur, err := c.UpdateMany(ctx, bson.D{{"name" , "rose" }}, update) if err != nil { log.Fatal(err) } fmt.Printf("ur.ModifiedCount: %v\n" , ur.ModifiedCount) }
删除 1 2 3 4 5 6 7 8 9 10 11 func delete () { initDb() c := client.Database("go_db" ).Collection("Student" ) ctx := context.TODO() dr, err := c.DeleteMany(ctx, bson.D{{"age" , 20 }}) if err != nil { fmt.Printf("err: %v\n" , err) } fmt.Printf("dr.DeletedCount: %v\n" , dr.DeletedCount) }
gorm 安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
创建表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package mainimport ( _ "github.com/go-sql-driver/mysql" "gorm.io/driver/mysql" "gorm.io/gorm" ) type Product struct { gorm.Model Code string Price uint } func main () { dsn := "root:runaway0926@tcp(127.0.0.1:3306)/golang_db?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic ("failed to connect database" ) } db.AutoMigrate(&Product{}) }
插入数据 1 2 3 4 5 6 7 8 func insert (db *gorm.DB) { p := Product{ Code: "1001" , Price: 100 , } db.Create(&p) }
更新 1 2 3 4 5 6 7 func update (db *gorm.DB) { var p Product db.First(&p, 1 ) db.Model(&p).Update("Price" , 1000 ) }
查询 1 2 3 4 5 6 7 8 func find (db *gorm.DB) { var p Product db.First(&p, 1 ) fmt.Printf("p: %v\n" , p) }
删除 1 2 3 4 5 6 func delete (db *gorm.DB) { var p Product db.First(&p, 1 ) db.Delete(&p, 1 ) }
声明模型 1 2 3 4 5 6 7 8 type Product struct { gorm.Model Code string Price uint }
注意
1 2 3 4 5 6 7 8 9 10 func init () { dsn := "root:runaway0926@tcp(127.0.0.1:3306)/golang_db?charset=utf8mb4&parseTime=True&loc=Local" d, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic ("failed to connect database" ) } db = d }
1 2 3 4 5 6 7 8 9 10 11 func insert1 () { user := User{ Name: "tom" , Age: 20 , Brithday: time.Now(), } res := db.Create(&user) fmt.Printf("res.RowsAffected: %v\n" , res.RowsAffected) fmt.Printf("user.ID: %v\n" , user.ID) }
1 2 3 4 5 6 7 8 9 10 11 var user = User{ Name: "tom" , Age: 20 , Brithday: time.Now(), } func insert2 () { db.Select("Name" , "Age" , "CreateAt" ).Create(&user) }
批量添加 1 2 3 4 5 6 7 8 9 func insert3 () { var users = []User{{Name: "jinzhu1" }, {Name: "jinzhu2" }, {Name: "jinzhu3" }} db.Create(&users) } 注意这里需要修改sql_model 在my.ini 添加 sql_mode=NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO
gin 今天用vscode构建gin的时候
首先执行
接着上面显示下载好了
但是开始写的时候,包含这个包爆红了那么我们怎么解决呢?
步骤如下:
go env -w GOSUMDB=off
go env -w GO111MODULE=on
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
然后再输入
go get github.com/gin-gonic/gin
如下图所示
然后再看我们的代码
就不飘红啦
那么接下来,gin,启动!
离谱,怎么跑不起来,仔细琢磨一番
会不会是端口被占用了?
查看端口占用
win+r,cmd 老朋友了
netstat -ano | findstr “8082”
如果输入上面的信息没有显示,说明有端口占用情况
那么问题究竟是什么呢?
少写了个:
我真谢谢你
那么继续,gin,启动!
哎嘿,跑起来了,那么我们到8082端口看看
芜湖,起飞