diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/go-base.iml b/.idea/go-base.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/go-base.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..051af37 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/array/arrayTest.go b/array/arrayTest.go new file mode 100644 index 0000000..0e27eee --- /dev/null +++ b/array/arrayTest.go @@ -0,0 +1,29 @@ +package main + +import "fmt" + +func main() { + //arr := [...][3]int{{1,1,1},{2,2,2},{3,3,3}} + //for k1, v1 := range arr { + // for k2, v2 := range v1 { + // fmt.Printf("(%d,%d)=%d ",k1,k2,v2) + // } + // fmt.Println() + //} + arr := [5]int{} + printArr(&arr) + fmt.Println(arr) + fmt.Printf("arr: %p\n",&arr) + //arr2 := [...]int{1,2,3,4,5} + //printArr(&arr2) + //fmt.Printf("arr2: %p\n",&arr2) +} + +func printArr(arr *[5]int) { + arr[0] = 1100 + for k1, v1 := range arr { + fmt.Printf("(%d,%d)",k1,v1) + } + fmt.Printf("arr: %p\n",&arr) + fmt.Println() +} \ No newline at end of file diff --git a/array/sumTest.go b/array/sumTest.go new file mode 100644 index 0000000..2f29d4d --- /dev/null +++ b/array/sumTest.go @@ -0,0 +1,27 @@ +package main + +import "fmt" + +func sumArr(arr *[5]int) { + fmt.Printf("arr: %p\n",&arr) + arr[0]=12132 +} + +func main() { + arr := [5]int{1,2,3,4,5} + //fmt.Printf("arr: %p\n",&arr) + //sumArr(&arr) + //fmt.Println(arr[0]) + findArr(5,arr) +} + +func findArr(sum int, arr [5]int) { + for i := 0; i < len(arr); i++ { + for j := i+1; j < len(arr); j++ { + target := arr[i] + arr[j] + if target == sum{ + fmt.Printf("(%d,%d)\n",i,j) + } + } + } +} diff --git a/chan/channelDemo01.go b/chan/channelDemo01.go new file mode 100644 index 0000000..4f530cd --- /dev/null +++ b/chan/channelDemo01.go @@ -0,0 +1,32 @@ +package main + +import ( + "context" + "fmt" + "time" +) + + + +func main() { + ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second) + defer cancel() + go doSomethingCool(ctx) + select { + case <-ctx.Done(): + fmt.Println("oh no, I've exceeded the deadline") + } +} + +func doSomethingCool(ctx context.Context) { + for { + select { + case <-ctx.Done(): + fmt.Println("timed out") + return + default: + fmt.Println("doing something cool") + } + time.Sleep(500 * time.Millisecond) + } +} \ No newline at end of file diff --git a/chan/channelDemo02.go b/chan/channelDemo02.go new file mode 100644 index 0000000..bd9db36 --- /dev/null +++ b/chan/channelDemo02.go @@ -0,0 +1,28 @@ +package main + +import "fmt" + +func myAppend(s []int) []int { + // 这里 s 虽然改变了,但并不会影响外层函数的 s + s = append(s, 100) + return s +} +func myAppendPtr(s *[]int) { + // 会改变外层 s 本身 + *s = append(*s, 100) + return +} +func main() { + s := make([]int, 2, 4) + s[0] = 1 + s[1] = 1 + fmt.Println("len", len(s)) + fmt.Println("cap", cap(s)) + fmt.Println(&s) + newS := myAppend(s) + fmt.Println(s) + fmt.Println(newS) + s = newS + myAppendPtr(&s) + fmt.Println(s) +} diff --git a/chan/channelDemo03.go b/chan/channelDemo03.go new file mode 100644 index 0000000..040b3dc --- /dev/null +++ b/chan/channelDemo03.go @@ -0,0 +1,103 @@ +package main + +import ( + "context" + "fmt" + "log" + "net/http" + _ "net/http/pprof" + "time" +) + +func setup() { + // 这里面有一些初始化的操作 +} + +func main() { + setup() + + // 用于监听服务退出, 这里使用了两个 goroutine,所以 cap 为2 + done := make(chan error, 2) + + // 无缓冲的通道,用于控制服务退出,传入同一个 stop,做到只要有一个服务退出了那么另外一个服务也会随之退出 + stop := make(chan struct{}, 0) + + // for debug + go func() { + // pprof 传递一个 channel + fmt.Println("pprof start...") + done <- pprof(stop) + fmt.Printf("err1:%v\n", done) + + }() + + // 主服务 + go func() { + fmt.Println("app start...") + done <- app(stop) + fmt.Printf("err2:%v\n", done) + }() + + // stopped 用于判断当前 stop 的状态 + var stopped bool + + // 这里循环读取 done 这个 channel + // 只要有一个退出了,我们就关闭 stop channel + for i := 0; i < cap(done); i++ { + + // 对于有缓冲的chan, chan中无值会一直处于阻塞状态 + // 对于app 服务会一直阻塞状态,不会有 数据写入到done 通道,只有在5s后,模拟的 pprof会有err写入chan,此时才会触发以下逻辑 + if err := <-done; err != nil { + log.Printf("server exit err: %+v", err) + } + + if !stopped { + stopped = true + // 通过关闭 无缓冲的channel 来通知所有的 读 stop相关的goroutine退出 + close(stop) + } + } +} + +// http 服务 +func app(stop <-chan struct{}) error { + mux := http.NewServeMux() + mux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("pong")) + }) + + return server(mux, ":8080", stop) +} + +func pprof(stop <-chan struct{}) error { + // 注意这里主要是为了模拟服务意外退出,用于验证一个服务退出,其他服务同时退出的场景 + // 因为这里没有返回err, 所以done chan中无法接收到值, 主程序中会一直阻塞住 + go func() { + server(http.DefaultServeMux, ":8081", stop) + }() + + time.Sleep(5 * time.Second) + // 模拟出错 + return fmt.Errorf("mock pprof exit") +} + +// 启动一个服务 +func server(handler http.Handler, addr string, stop <-chan struct{}) error { + + s := http.Server{ + Handler: handler, + Addr: addr, + } + + // 这个 goroutine 控制退出,因为 stop channel 只要close或者是写入数据,这里就会退出 + go func() { + // 无缓冲channel等待,写入或者关闭 + <-stop + log.Printf("server will exiting, addr: %s", addr) + // 此时 httpApi 服务就会优雅的退出 + s.Shutdown(context.Background()) + }() + + // 没有触发异常的话,会一直处于阻塞 + return s.ListenAndServe() +} \ No newline at end of file diff --git a/chan/channelDemo04.go b/chan/channelDemo04.go new file mode 100644 index 0000000..b49190a --- /dev/null +++ b/chan/channelDemo04.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "time" +) + +// DeferRecover defer recover from panic. +func DeferRecover(tag string, handlePanic func(error)) func() { + return func() { + if err := recover(); err != nil { + fmt.Println(tag) + if handlePanic != nil { + handlePanic(fmt.Errorf("%v", err)) + } + } + } +} + +// WithRecover recover from panic. +func WithRecover(tag string, f func(), handlePanic func(error)) { + defer DeferRecover(tag, handlePanic)() + f() + panic("test") +} + +// Go is a wrapper of goroutine with recover. +func Go(name string, f func(), handlePanic func(error)) { + go WithRecover(fmt.Sprintf("goroutine %s", name), f, handlePanic) +} + +func main() { + Go("test-final", func() { + fmt.Println("business") + + },func(err error){ + fmt.Println("recovery:",err) + }) + + time.Sleep(3*time.Millisecond) +} \ No newline at end of file diff --git a/chan/channelDemo05.go b/chan/channelDemo05.go new file mode 100644 index 0000000..70e99d9 --- /dev/null +++ b/chan/channelDemo05.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + "time" +) + +func main(){ + tc:= make(chan int, 1) + go func() { + for i := 0; i <10; i++ { + time.Sleep(time.Second) + tc <- i + } + }() + //<-tc + fmt.Println("tick") + select { + + } + //tk:= time.Tick(time.Second) + //<- tk + //select { + // + //} +} diff --git a/defer/deferDemo.go b/defer/deferDemo.go new file mode 100644 index 0000000..6c8007f --- /dev/null +++ b/defer/deferDemo.go @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func main() { + defer func() { + if err := recover(); err != nil { + fmt.Println("nothing happened") + fmt.Println(err) + } + }() + go func() { + panic("go routine panic") + }() + fmt.Println("nothing happened") +} diff --git a/dingding/main.go b/dingding/main.go new file mode 100644 index 0000000..7b0be62 --- /dev/null +++ b/dingding/main.go @@ -0,0 +1,60 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + "time" +) + +func main() { + sendMsg("azsdcasd") +} +const httpTimeoutSecond = time.Duration(30) * time.Second +type message string + +type Response struct { + ErrMsg string `json:"errmsg"` + ErrCode int64 `json:"errcode"` +} +func sendMsg(message) (*Response, error){ + res := &Response{} + pushURL := "https://oapi.dingtalk.com/robot/send?access_token=068bb8f58f178d2e517c4b6d078796f9cb0466412641f0a0cbd952bbb754b4bd" + req, err := http.NewRequest(http.MethodPost,pushURL,strings.NewReader(`{"msgtype": "text","text": {"content": "starkwang"}}`)) + if err != nil { + fmt.Println("01") + } + + req.Header.Add("Accept-Charset","utf8") + req.Header.Add("Content-Type","application/json") + + client := new(http.Client) + + client.Timeout = httpTimeoutSecond + fmt.Println(req) + resp ,err := client.Do(req) + fmt.Println(resp) + if err != nil { + fmt.Println("02") + } + + defer resp.Body.Close() + + resultByte, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println("03") + } + err = json.Unmarshal(resultByte, &res) + if err != nil { + fmt.Errorf("unmarshal http response body from json error = %v", err) + } + if res.ErrCode != 0 { + return res, fmt.Errorf("send message to dingtalk error = %s", res.ErrMsg) + } + + fmt.Println("res----",res) + + return res, nil +} \ No newline at end of file diff --git a/error/errorDemo.go b/error/errorDemo.go new file mode 100644 index 0000000..14a4c4b --- /dev/null +++ b/error/errorDemo.go @@ -0,0 +1,57 @@ +package main + +import ( + "fmt" + "math/rand" + "sync" + "time" +) + +var ( + // 定义 goroutine 数量 + goroutineCount = 4 + // 任务数 + taskCount = 10 + wg sync.WaitGroup +) + +func main() { + // 有缓冲通道 类型为 string, 缓冲数 taskCount 为 10 + tasks := make(chan string, taskCount) + wg.Add(goroutineCount) + + for gr:=1; gr<=goroutineCount; gr++{ + // 开启多个 goroutine 执行任务 + go worker(tasks, gr) + } + + // 存放任务到任务通道中 + for task :=1; task <= taskCount; task++ { + tasks <- fmt.Sprintf("Task %d\n", task) + } + // 执行完所有的 goroutine 后,关闭通道 + close(tasks) + + // 阻塞主线程,等到所有 goroutine 执行完毕在往下执行 + wg.Wait() +} + +func worker(tasks chan string, worker int) { + defer wg.Done() + + for { + // 从任务通道中取任务 和 通道 是否关闭的状态 + task, ok := <-tasks + // 通道已经关闭 + if !ok { + fmt.Printf("Worker %d: shutdown\n", worker) + return + } + // 模拟工作 + sleep := rand.Int63n(100) + time.Sleep(time.Duration(sleep) * time.Millisecond) + fmt.Printf("Worker %d started %s", worker, task) + // 完成工作 + fmt.Printf("Worker %d completed %s\n", worker, task) + } +} \ No newline at end of file diff --git a/extend/extend.go b/extend/extend.go new file mode 100644 index 0000000..5fe24dd --- /dev/null +++ b/extend/extend.go @@ -0,0 +1,31 @@ +package extend + +import "fmt" + +type Animal struct { + name string +} + +func (a *Animal) move() { + fmt.Printf("%s会动!\n", a.name) +} + +type Dog struct { + Feet int8 + *Animal +} + +func (d Dog) wang() { + fmt.Printf("%s会汪汪汪~\n", d.name) +} + +func main() { + dog := Dog{ + Feet: 4, + Animal: &Animal{ + name: "XI", + }, + } + dog.move() + dog.wang() +} \ No newline at end of file diff --git a/function/funDemo.go b/function/funDemo.go new file mode 100644 index 0000000..3050fe7 --- /dev/null +++ b/function/funDemo.go @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + s1 := test(func() string { + return "100" + }) + fmt.Println(s1) +} + +func test(fn func() string) string { + return fn() +} diff --git a/function/funDemo02.go b/function/funDemo02.go new file mode 100644 index 0000000..fc47891 --- /dev/null +++ b/function/funDemo02.go @@ -0,0 +1,18 @@ +package main + +import "fmt" + +func main() { + slice1 := []int{1,2,3,4,5,6} + println(argTest("sum: %d", slice1...)) + fmt.Println(slice1[0]) +} + +func argTest(s string, n ...int) string{ + var sum int + n[0] = 10 + for _, v := range n { + sum += v + } + return fmt.Sprint(s,sum) +} diff --git a/function/funDemo03.go b/function/funDemo03.go new file mode 100644 index 0000000..5fbf2ef --- /dev/null +++ b/function/funDemo03.go @@ -0,0 +1,13 @@ +package main + +func main() { + println(add(1, 2)) +} + +func add(a, b int) (c int) { + defer func() { + c += 10 + }() + c = a + b + return +} diff --git a/function/funDemo04.go b/function/funDemo04.go new file mode 100644 index 0000000..e7bd655 --- /dev/null +++ b/function/funDemo04.go @@ -0,0 +1,16 @@ +package main + +import "fmt" + +type Test struct { + name string +} + +func (t *Test) Close() { + fmt.Println(t.name, " closed") +} +func main() { + var slices []string + slices = append(slices, "1") +} + diff --git a/function/funDemo05.go b/function/funDemo05.go new file mode 100644 index 0000000..8479256 --- /dev/null +++ b/function/funDemo05.go @@ -0,0 +1,16 @@ +package main + +func deferTest(x int) { + defer println("a") + defer println("b") + + defer func() { + println(100/x) + }() + + defer println("c") +} + +func main() { + deferTest(0) +} diff --git a/function/funDemo06.go b/function/funDemo06.go new file mode 100644 index 0000000..3eb5b4b --- /dev/null +++ b/function/funDemo06.go @@ -0,0 +1,17 @@ +package main + +func deferT() { + x, y := 10, 20 + + defer func(i, j int) { + println("defer:", i, j) + }(x, y) + + x += 100 + y += 10 + println("x = ", x , "y = ",y) +} + +func main() { + deferT() +} diff --git a/function/funDemo07.go b/function/funDemo07.go new file mode 100644 index 0000000..3676fb7 --- /dev/null +++ b/function/funDemo07.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +type HandleFunc func(string) + +func main() { + //defer func() { + // if err := recover(); err!=nil{ + // fmt.Println(err) + // } + //}() + //ch := make(chan int, 10) + //close(ch) + //ch <- 100 + handleFunc := HandleFunc(func(s string) { + fmt.Println(s) + }) + handleFunc("1") +} diff --git a/function/funDemo08.go b/function/funDemo08.go new file mode 100644 index 0000000..fef24ed --- /dev/null +++ b/function/funDemo08.go @@ -0,0 +1,28 @@ +package main + +import "fmt" + +// 返回2个函数类型的返回值 +func test01(base int) (func(int) int, func(int) int) { + // 定义2个函数,并返回 + // 相加 + add := func(i int) int { + base += i + return base + } + // 相减 + sub := func(i int) int { + base -= i + return base + } + // 返回 + return add, sub +} + +func main() { + f1, f2 := test01(10) + // base一直是没有消 + fmt.Println(f1(1), f2(2)) + // 此时base是9 + fmt.Println(f1(3), f2(4)) +} \ No newline at end of file diff --git a/gin/router1.go b/gin/router1.go new file mode 100644 index 0000000..2a72895 --- /dev/null +++ b/gin/router1.go @@ -0,0 +1,19 @@ +package main + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + + +func main() { + r := gin.Default() + r.GET("https://console.lstack-dev.cn/idp/catalog/components", func(c *gin.Context) { + c.String(http.StatusOK, "hello word") + }) + //r.POST("/xxxpost",getting) + //r.PUT("/xxxput") + ////监听端口默认为8080 + //r.Run(":8000") +} diff --git a/go-redis/redisDemo01.go b/go-redis/redisDemo01.go new file mode 100644 index 0000000..8e7f17d --- /dev/null +++ b/go-redis/redisDemo01.go @@ -0,0 +1,29 @@ +package go_redis + +import ( + "context" + "fmt" + "github.com/go-redis/redis/v8" +) + +var rdb *redis.Client + +func init() { + rdb = redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password set + DB: 0, // use default DB + }) +} + +func redisGet() { + val, err := rdb.Do(context.Background(), "get", "mail_log").Text() + if err != nil { + if err == redis.Nil { + fmt.Println("key does not exists") + return + } + panic(err) + } + fmt.Println(val) +} diff --git a/go-redis/redisDemo01_test.go b/go-redis/redisDemo01_test.go new file mode 100644 index 0000000..c28303f --- /dev/null +++ b/go-redis/redisDemo01_test.go @@ -0,0 +1,7 @@ +package go_redis + +import "testing" + +func TestRedisGet(t *testing.T) { + redisGet() +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e5ab1a8 --- /dev/null +++ b/go.mod @@ -0,0 +1,46 @@ +module go-base + +go 1.17 + +require ( + github.com/casbin/casbin/v2 v2.45.0 + github.com/casbin/xorm-adapter/v2 v2.5.1 + github.com/gin-gonic/gin v1.7.7 + github.com/go-redis/redis/v8 v8.11.5 + github.com/go-sql-driver/mysql v1.6.0 + github.com/joomcode/errorx v1.1.0 + gopkg.in/go-playground/validator.v9 v9.31.0 +) + +require ( + github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.13.0 // indirect + github.com/go-playground/universal-translator v0.17.0 // indirect + github.com/go-playground/validator/v10 v10.4.1 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect + github.com/google/go-cmp v0.5.7 // indirect + github.com/json-iterator/go v1.1.11 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/leodido/go-urn v1.2.0 // indirect + github.com/lib/pq v1.8.0 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/stretchr/testify v1.7.1 // indirect + github.com/syndtr/goleveldb v1.0.0 // indirect + github.com/ugorji/go/codec v1.1.7 // indirect + golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 // indirect + golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/go-playground/assert.v1 v1.2.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + xorm.io/builder v0.3.7 // indirect + xorm.io/xorm v1.0.3 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2ab383d --- /dev/null +++ b/go.sum @@ -0,0 +1,217 @@ +gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= +gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/casbin/casbin/v2 v2.28.3/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= +github.com/casbin/casbin/v2 v2.45.0 h1:sMeqdcG/M+vkxS3WvQbkfGQx3OSEnkTIUDOtWHwEEqQ= +github.com/casbin/casbin/v2 v2.45.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= +github.com/casbin/xorm-adapter/v2 v2.5.1 h1:BkpIxRHKa0s3bSMx173PpuU7oTs+Zw7XmD0BIta0HGM= +github.com/casbin/xorm-adapter/v2 v2.5.1/go.mod h1:AeH4dBKHC9/zYxzdPVHhPDzF8LYLqjDdb767CWJoV54= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/joomcode/errorx v1.1.0 h1:dizuSG6yHzlvXOOGHW00gwsmM4Sb9x/yWEfdtPztqcs= +github.com/joomcode/errorx v1.1.0/go.mod h1:eQzdtdlNyN7etw6YCS4W4+lu442waxZYw5yvz0ULrRo= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= +github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 h1:kETrAMYZq6WVGPa8IIixL0CaEcIUNi+1WX7grUoi3y8= +golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= +gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI= +xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= +xorm.io/xorm v1.0.3 h1:3dALAohvINu2mfEix5a5x5ZmSVGSljinoSGgvGbaZp0= +xorm.io/xorm v1.0.3/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4= diff --git a/goroutine/goroutineDemo.go b/goroutine/goroutineDemo.go new file mode 100644 index 0000000..2ffe4b1 --- /dev/null +++ b/goroutine/goroutineDemo.go @@ -0,0 +1,84 @@ +package main + +import ( + "context" + "fmt" + "log" + "net/http" + _ "net/http/pprof" + "time" +) + +func setup() { + // 这里面有一些初始化的操作 +} + +func main() { + setup() + + // 用于监听服务退出 + done := make(chan error, 2) + // 用于控制服务退出,传入同一个 stop,做到只要有一个服务退出了那么另外一个服务也会随之退出 + stop := make(chan struct{}, 0) + // for debug + go func() { + done <- pprof(stop) + }() + + // 主服务 + go func() { + done <- app(stop) + }() + + // stoped 用于判断当前 stop 的状态 + var stoped bool + // 这里循环读取 done 这个 channel + // 只要有一个退出了,我们就关闭 stop channel + for i := 0; i < cap(done); i++ { + if err := <-done; err != nil { + log.Printf("server exit err: %+v", err) + } + + if !stoped { + stoped = true + close(stop) + } + } +} + +func app(stop <-chan struct{}) error { + mux := http.NewServeMux() + mux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("pong")) + }) + + return server(mux, ":8080", stop) +} + +func pprof(stop <-chan struct{}) error { + // 注意这里主要是为了模拟服务意外退出,用于验证一个服务退出,其他服务同时退出的场景 + go func() { + server(http.DefaultServeMux, ":8081", stop) + }() + + time.Sleep(5 * time.Second) + return fmt.Errorf("mock pprof exit") +} + +// 启动一个服务 +func server(handler http.Handler, addr string, stop <-chan struct{}) error { + s := http.Server{ + Handler: handler, + Addr: addr, + } + + // 这个 goroutine 我们可以控制退出,因为只要 stop 这个 channel close 或者是写入数据,这里就会退出 + // 同时因为调用了 s.Shutdown 调用之后,http 这个函数启动的 http server 也会优雅退出 + go func() { + <-stop + log.Printf("server will exiting, addr: %s", addr) + s.Shutdown(context.Background()) + }() + + return s.ListenAndServe() +} \ No newline at end of file diff --git a/goroutine/goroutineDemo01.go b/goroutine/goroutineDemo01.go new file mode 100644 index 0000000..4d97c68 --- /dev/null +++ b/goroutine/goroutineDemo01.go @@ -0,0 +1,12 @@ +package main + +import "fmt" + +func Hello() { + fmt.Println("sdsadad") +} + +func main() { + go Hello() + fmt.Println("goroutine") +} diff --git a/goroutine/goroutineDemo02.go b/goroutine/goroutineDemo02.go new file mode 100644 index 0000000..4d270d5 --- /dev/null +++ b/goroutine/goroutineDemo02.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "sync" +) +var wg sync.WaitGroup + +func hello(i int) { + defer wg.Done() // goroutine结束就登记-1 + fmt.Println("Hello Goroutine!", i) +} +func main() { + + for i := 0; i < 10; i++ { + wg.Add(1) // 启动一个goroutine就登记+1 + go hello(i) + } + wg.Wait() // 等待所有登记的goroutine都结束 +} \ No newline at end of file diff --git a/goroutine/goroutineDemo03.go b/goroutine/goroutineDemo03.go new file mode 100644 index 0000000..866d4d2 --- /dev/null +++ b/goroutine/goroutineDemo03.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + // 合起来写 + go func() { + i := 0 + for { + i++ + fmt.Printf("new goroutine: i = %d\n", i) + time.Sleep(time.Second) + } + }() + i := 0 + for { + i++ + fmt.Printf("main goroutine: i = %d\n", i) + time.Sleep(time.Second) + if i == 2 { + break + } + } +} \ No newline at end of file diff --git a/goroutine/goroutineDemo04.go b/goroutine/goroutineDemo04.go new file mode 100644 index 0000000..bb3dd25 --- /dev/null +++ b/goroutine/goroutineDemo04.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "runtime" +) + +func main() { + go func() { + defer fmt.Println("A.defer") + func() { + defer fmt.Println("B.defer") + // 结束协程 + runtime.Goexit() + defer fmt.Println("C.defer") + fmt.Println("B") + }() + fmt.Println("A") + }() + for { + } +} \ No newline at end of file diff --git a/goroutine/goroutineDemo05.go b/goroutine/goroutineDemo05.go new file mode 100644 index 0000000..c678ca4 --- /dev/null +++ b/goroutine/goroutineDemo05.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + "runtime" + "time" +) + +func a() { + for i := 1; i < 10; i++ { + fmt.Println("A:", i) + } +} + +func b() { + for i := 1; i < 10; i++ { + fmt.Println("B:", i) + } +} + +func main() { + runtime.GOMAXPROCS(1) + go a() + go b() + time.Sleep(time.Second) +} \ No newline at end of file diff --git a/hello/hello.go b/hello/hello.go new file mode 100644 index 0000000..19a75c0 --- /dev/null +++ b/hello/hello.go @@ -0,0 +1,25 @@ +package hello + +import "fmt" +import "os" + +func init() { + fmt.Println("imp-init() come here.") +} + +func Print() { + fmt.Println("Hello!") +} + +func main() { + buf := make([]byte, 1024) + f, _ := os.Open("D:\\GoProject\\go-base\\text.txt") + defer f.Close() + for{ + n, _ := f.Read(buf) + if n == 0{ + break + } + os.Stdout.Write(buf[:n]) + } +} \ No newline at end of file diff --git a/inter/interface1.go b/inter/interface1.go new file mode 100644 index 0000000..5c7d5bb --- /dev/null +++ b/inter/interface1.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + "reflect" +) + +type People interface { + Speak(string) string +} + +type Student11 struct{ + Name string `json:"name"` + Age int `json:"age"` + +} + +func (stu *Student11) Speak(think string) (talk string) { + if think == "sb" { + talk = "你是个大帅比" + } else { + talk = "您好" + } + return +} + + +func main() { + h := Student11{ + Name: "小王", + Age: 15, + } + retH := reflect.TypeOf(h) + of := reflect.ValueOf(h) + //获取结构体里的名称 + for i := 0; i < retH.NumField(); i++ { + field := retH.Field(i) + fmt.Println("结构体里的字段名",field.Name) + fmt.Println("结构体里的字段属性:",field.Type) + fmt.Println("结构体里面的字段的tag标签",field.Tag) + fmt.Println(of.Field(i).Interface()) + } + //提取tag标签里的信息 + name, bool := retH.FieldByName("Name") + if bool { + fmt.Println("tag标签的信息为",name.Tag.Get("json")) + } +} \ No newline at end of file diff --git a/main.exe b/main.exe new file mode 100644 index 0000000..7d6c4f4 Binary files /dev/null and b/main.exe differ diff --git a/main.go b/main.go new file mode 100644 index 0000000..03fa07f --- /dev/null +++ b/main.go @@ -0,0 +1,10 @@ +package main + +import "fmt" + +import _ "go-base/hello" + +func main() { + fmt.Println("main") +} + diff --git a/map/mapDemo.go b/map/mapDemo.go new file mode 100644 index 0000000..ee0c353 --- /dev/null +++ b/map/mapDemo.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + map1 := make(map[string]string, 16) + map1["admin01"] = "Feyoung" + map1["admin02"] = "Feyoung" + v, ok := map1["admin01"] + if ok { + fmt.Printf(v) + } +} diff --git a/map/mapDemo02.go b/map/mapDemo02.go new file mode 100644 index 0000000..c4aa7ae --- /dev/null +++ b/map/mapDemo02.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + + func main() { + var mapSlice = make([]map[string]string, 3) + for index, value := range mapSlice { + fmt.Printf("index:%d value:%v\n", index, value) + } + fmt.Println("after init") + // 对切片中的map元素进行初始化 + mapSlice[0] = make(map[string]string, 10) + mapSlice[0]["name"] = "王五" + mapSlice[0]["password"] = "123456" + mapSlice[0]["address"] = "红旗大街" + for index, value := range mapSlice { + fmt.Printf("index:%d value:%v\n", index, value) + } + } + diff --git a/map/mapDemo03.go b/map/mapDemo03.go new file mode 100644 index 0000000..c1e5ad4 --- /dev/null +++ b/map/mapDemo03.go @@ -0,0 +1,23 @@ +package main + +import "fmt" + +func main() { + sliceMap := make(map[string][]string, 3) + fmt.Println(sliceMap) + key := "中国" + v, ok := sliceMap[key] + if !ok{ + v = make([]string,0,2) + } + v = append(v,"武汉","杭州") + sliceMap[key] = v + + for key, slices := range sliceMap { + fmt.Println("key: ", key) + for _, value := range slices { + fmt.Println(value) + } + } + +} diff --git a/middleware/middlewareDemo.go b/middleware/middlewareDemo.go new file mode 100644 index 0000000..507a1d1 --- /dev/null +++ b/middleware/middlewareDemo.go @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "time" + + "github.com/gin-gonic/gin" +) + +// 定义中间 +func MiddleWare() gin.HandlerFunc { + return func(c *gin.Context) { + t := time.Now() + fmt.Println("中间件开始执行了") + // 设置变量到Context的key中,可以通过Get()取 + c.Set("request", "中间件") + // 执行函数 + c.Next() + // 中间件执行完后续的一些事情 + status := c.Writer.Status() + fmt.Println("中间件执行完毕", status) + t2 := time.Since(t) + fmt.Println("time:", t2) + } +} + +// 定义中间 +func myTime(c *gin.Context) { + start := time.Now() + c.Next() + // 统计时间 + since := time.Since(start) + fmt.Println("程序用时:", since) +} + + +func main() { + // 1.创建路由 + // 默认使用了2个中间件Logger(), Recovery() + r := gin.Default() + r.Use(myTime) + //局部中间键使用 + r.GET("/ce", func(c *gin.Context) { + // 取值 + req, _ := c.Get("request") + fmt.Println("request:", req) + // 页面接收 + c.JSON(200, gin.H{"request": req}) + }) + r.Run() +} \ No newline at end of file diff --git a/middleware/validateDemo.go b/middleware/validateDemo.go new file mode 100644 index 0000000..1f07712 --- /dev/null +++ b/middleware/validateDemo.go @@ -0,0 +1,49 @@ +package main + + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "gopkg.in/go-playground/validator.v9" +) + +/* + 对绑定解析到结构体上的参数,自定义验证功能 + 比如我们需要对URL的接受参数进行判断,判断用户名是否为root如果是root通过否则返回false +*/ +type Login struct { + User string `uri:"user" validate:"checkName"` + Password string `uri:"password"` +} + +// 自定义验证函数 +func checkName(fl validator.FieldLevel) bool { + if fl.Field().String() != "root" { + return false + } + return true +} +func main() { + r := gin.Default() + validate := validator.New() + r.GET("/:user/:password", func(c *gin.Context) { + var login Login + //注册自定义函数,与struct tag关联起来 + err := validate.RegisterValidation("checkName", checkName) + if err := c.ShouldBindUri(&login); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + err = validate.Struct(login) + if err != nil { + for _, err := range err.(validator.ValidationErrors) { + fmt.Println(err) + } + return + } + fmt.Println("success") + }) + r.Run() +} \ No newline at end of file diff --git a/point/closureDemo.go b/point/closureDemo.go new file mode 100644 index 0000000..602d06e --- /dev/null +++ b/point/closureDemo.go @@ -0,0 +1,86 @@ +package main + + +import "fmt" + +func main() { + //Test() + //Test1()// 5 5 5 5 5 除了初始化赋值外还被闭包修改--->捕获变量i的地址 + //Test2()// 4 4 4 4 4 除了初始化赋值外还被外层函数修改--->捕获变量t的地址 + Test3()// 0 1 2 3 4 只被初始化赋值--->值拷贝t +} + +func Test() { + fmt.Println("test start--------------") + fs := Closure() + println(fs()) + println(fs()) +} + +func Closure() func() int { + i := 2 + i++ + return func() int { + return i + } +} + +func Test1() { + fmt.Println("test1 start--------------") + fs := Closure1() + for _, f := range fs { + f() + } + fmt.Println("test1 end--------------") +} + +func Closure1() (fs [5]func()) { + for i := 0; i < 5; i++ { + fmt.Println("i address=",&i) + fs[i] = func() { + fmt.Println(i, &i) + } + } + return +} + +func Test2() { + fmt.Println("test2 start--------------") + fs := Closure2() + for _, f := range fs { + f() + } + fmt.Println("test2 end--------------") +} + +func Closure2() (fs [5]func()) { + t := 0 + for i := 0; i < 5; i++ { + t = i + fmt.Println("t address=",&t) + fs[i] = func() { + fmt.Println(t, &t) + } + } + return +} + +func Test3() { + fmt.Println("test3 start--------------") + fs := Closure3() + for _, f := range fs { + f() + } + fmt.Println("test3 end--------------") +} + +func Closure3() (fs [5]func()) { + for i := 0; i < 5; i++ { + t := i + fmt.Println("t address=",&t) + fs[i] = func() { + fmt.Println(t, &t) + } + } + return +} \ No newline at end of file diff --git a/point/funcDemo.go b/point/funcDemo.go new file mode 100644 index 0000000..d29a1c9 --- /dev/null +++ b/point/funcDemo.go @@ -0,0 +1,24 @@ +package main + +import "fmt" + +func main() { + demo := new(Demo) + fmt.Println(demo.Add()) + fmt.Println(demo.Add()) + fmt.Println(demo.Add()) + demo.Delete() +} + +type Demo struct { + i int +} + +func (d *Demo) Add() int { + d.i++ + return d.i +} + +func (d *Demo) Delete() { + fmt.Println(d.i) +} \ No newline at end of file diff --git a/point/pointDemo.go b/point/pointDemo.go new file mode 100644 index 0000000..434c439 --- /dev/null +++ b/point/pointDemo.go @@ -0,0 +1,13 @@ +package main + +func main() { + done, _ := bbb() + done() +} + +func bbb() (done func(), _ error) { + return func() { + print("bbb: surprise!") + done() + }, nil +} diff --git a/process/goTest.go b/process/goTest.go new file mode 100644 index 0000000..6f188ef --- /dev/null +++ b/process/goTest.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "io" + "os" +) + +type CustomReadWriter struct { + name string +} + +func (c CustomReadWriter) Read(p []byte) (n int, err error) { + fmt.Println(p) + return 1, nil +} + +func (c CustomReadWriter) Write(p []byte) (n int, err error) { + fmt.Println(p) + return 1, nil +} + +func main() { + /* + 将f赋值给rw后,rw的动态类型是CustomReadWriter,接口类型是io.ReadWriter + + + 这两项都在itab缓存中,但是下面的断言明显不成功。 + 所以,当断言成具体类型时,是不是应该直接检查rw的动态值的类型是不是与目标具体类型相等 + */ + var rw io.ReadWriter + f := CustomReadWriter{name: "poizon"} + rw = f + rf, ok := rw.(*os.File) + fmt.Println(rf, ok) +} \ No newline at end of file diff --git a/process/ifTest.go b/process/ifTest.go new file mode 100644 index 0000000..836a4d3 --- /dev/null +++ b/process/ifTest.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "io" + "os" +) + +func main() { + var w io.Writer + r, _ := os.Open("D:\\GoProject\\go-base\\text.txt") + w = r + rw, ok := w.(io.ReadWriter) + fmt.Println(rw, ok) + +} diff --git a/process/rangeTest.go b/process/rangeTest.go new file mode 100644 index 0000000..a3775e2 --- /dev/null +++ b/process/rangeTest.go @@ -0,0 +1,17 @@ +package main + +func main() { + s := []int{1, 2, 3, 4, 5} + + for i, v := range s { // 复制 struct slice { pointer, len, cap }。 + + if i == 0 { + s = s[:3] // 对 slice 的修改,不会影响 range。 + + s[2] = 100 // 对底层数据的修改。 + } + + println(i, v) + } + println(s[2]) +} diff --git a/process/switchTest.go b/process/switchTest.go new file mode 100644 index 0000000..0865991 --- /dev/null +++ b/process/switchTest.go @@ -0,0 +1,32 @@ +package main + +import "fmt" + +func main() { + grade := "B" + marks := 90 + switch marks { + case 90: grade = "A" + case 80: grade = "B" + case 50, 60, 70: + grade = "C" + default: + grade = "D" + } + + + switch { + case grade == "A" : + fmt.Printf("优秀!\n" ) + fallthrough + case grade == "B", grade == "C" : + fmt.Printf("良好\n" ) + case grade == "D" : + fmt.Printf("及格\n" ) + case grade == "F": + fmt.Printf("不及格\n" ) + default: + fmt.Printf("差\n" ) + } + fmt.Printf("你的等级是 %s\n", grade ) +} diff --git a/rbac/config.json b/rbac/config.json new file mode 100644 index 0000000..1c84a34 --- /dev/null +++ b/rbac/config.json @@ -0,0 +1,24 @@ +[ + { + "id": 0, + "host": "*", + "path": "**", + "method": "*", + "authorized_roles": [ + "*" + ], + "forbidden_roles": [ + "black_user" + ], + "allow_anyone": false + }, + { + "id":1, + "host": "domain.com", + "path": "/article", + "method": "{DELETE,POST,PUT}", + "authorized_roles": ["editor"], + "forbidden_roles": [], + "allow_anyone": false + } +] diff --git a/rbac/grbac.go b/rbac/grbac.go new file mode 100644 index 0000000..81e5c74 --- /dev/null +++ b/rbac/grbac.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "github.com/casbin/casbin/v2" + "github.com/casbin/casbin/v2/model" + xormadapter "github.com/casbin/xorm-adapter/v2" + _ "github.com/go-sql-driver/mysql" + "log" +) + +func main() { + // Initialize a Xorm adapter with MySQL database. + a, err := xormadapter.NewAdapter("mysql", "root:root@tcp(127.0.0.1:3306)/casbin?charset=utf8", true) + if err != nil { + log.Fatalf("error: adapter: %s", err) + } + + m, err := model.NewModelFromString(` +[request_definition] +r = sub, obj, act + +[policy_definition] +p = sub, obj, act + +[policy_effect] +e = some(where (p.eft == allow)) + +[role_definition] +g = _, _ + +[matchers] +m = r.sub == p.sub && r.obj == p.obj && r.act == p.act +`) + if err != nil { + log.Fatalf("error: model: %s", err) + } + + e, err := casbin.NewEnforcer(m, a) + if err != nil { + log.Fatalf("error: enforcer: %s", err) + } + + sub := "alice" // 想要访问资源的用户。 + obj := "data1" // 将被访问的资源。 + act := "read" // 用户对资源执行的操作。 + + ok, err := e.Enforce(sub, obj, act) + if err != nil { + // 处理err + } + + if ok == true { + // 允许alice读取data1 + fmt.Println("success") + } else { + // 拒绝请求,抛出异常 + fmt.Println("fail") + } + roles, err := e.GetRolesForUser("tom") + if err == nil { + fmt.Println(roles) + } + +} diff --git a/reflect/reflectDemo.go b/reflect/reflectDemo.go new file mode 100644 index 0000000..b091db1 --- /dev/null +++ b/reflect/reflectDemo.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "reflect" +) + +type Student struct { + Name string `orm:"name"` + Age int `orm:"age"` +} + +func (s *Student)Update(){ + s.Age+=1 +} + +func (s Student)print(){ + fmt.Println(s.Name,s.Age) +} + +func (s Student)Show(){ + fmt.Println(s.Name,s.Age) +} + +func main() { + s := Student{Name:"BX",Age:18} + t :=reflect.TypeOf(s) + for i:=0;i结构体 + str := `{"Title":"101","Students":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":"男","Name":"stu02"},{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"},{"ID":5,"Gender":"男","Name":"stu05"},{"ID":6,"Gender":"男","Name":"stu06"},{"ID":7,"Gender":"男","Name":"stu07"},{"ID":8,"Gender":"男","Name":"stu08"},{"ID":9,"Gender":"男","Name":"stu09"}]}` + c1 := &Class{} + err = json.Unmarshal([]byte(str), c1) + if err != nil{ + fmt.Println("json marshal failed") + return + } + fmt.Printf("%#v\n", c1) +} \ No newline at end of file diff --git a/struct/mapSort.go b/struct/mapSort.go new file mode 100644 index 0000000..6c9de51 --- /dev/null +++ b/struct/mapSort.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "sort" +) + +func main() { + map1 := make(map[int]string, 5) + map1[1] = "www.topgoer.com" + map1[2] = "rpc.topgoer.com" + map1[5] = "ceshi" + map1[3] = "xiaohong" + map1[4] = "xiaohuang" + sli := []int{} + for k, _ := range map1 { + sli = append(sli,k) + } + sort.Ints(sli) + for i := 0; i < len(map1); i++ { + fmt.Println(map1[sli[i]]) + } +} diff --git a/struct/structDemo.go b/struct/structDemo.go new file mode 100644 index 0000000..a0802dc --- /dev/null +++ b/struct/structDemo.go @@ -0,0 +1,29 @@ +package main + +import "fmt" + +type person struct { + name string + age int +} + +func main() { + person := newPerson("Feyoung", 21) + fmt.Println(person) + person = person.Dream(22) + fmt.Println(person) + admin := newPerson("admin", 12223) + fmt.Println(admin) +} + +func (p person) Dream(age int) *person { + p.age = age + return &p +} + +func newPerson(name string, age int) *person { + return &person{ + name: name, + age: age, + } +} \ No newline at end of file diff --git a/struct/structDemo02.go b/struct/structDemo02.go new file mode 100644 index 0000000..33fc8de --- /dev/null +++ b/struct/structDemo02.go @@ -0,0 +1,31 @@ +package main + +import "fmt" + +type Animal struct { + name string +} + +func (a *Animal) move() { + fmt.Printf("%s会动!\n", a.name) +} + +type Dog struct { + Feet int8 + *Animal +} + +func (d *Dog) wang() { + fmt.Printf("%s会汪汪汪~\n", d.name) +} + +func main() { + d1 := Dog{ + Feet: 4, + Animal: &Animal{ + name: "jj", + }, + } + d1.wang() + d1.move() +} diff --git a/struct/structDemo03.go b/struct/structDemo03.go new file mode 100644 index 0000000..68c811f --- /dev/null +++ b/struct/structDemo03.go @@ -0,0 +1,49 @@ +package main + +import "fmt" + +type Teacher struct { + name string + age int +} + +type Person struct { + name string + age int8 +} + +func (p *Person) SetAge2(newAge int8) { + p.age = newAge +} + +func NewPerson(name string,age int8) *Person { + return &Person{ + name: name, + age: age, + } +} + +func main() { + p1 := NewPerson("测试", 25) + fmt.Println(p1.age) + p1.SetAge2(30) + fmt.Println(p1.age) +} + + +//func main() { +// m := make(map[string]Teacher) +// teachers := []Teacher{ +// {name: "Feyoung1", age: 10}, +// {name: "Feyoung2", age: 10}, +// {name: "Feyoung3", age: 10}, +// } +// for _, teacher := range teachers { +// m[teacher.name] = teacher +// } +// +// for key, value := range m { +// fmt.Println("key:",key,"value: ",value) +// } +// +//} \ No newline at end of file diff --git a/struct/tagStruct.go b/struct/tagStruct.go new file mode 100644 index 0000000..39be5f5 --- /dev/null +++ b/struct/tagStruct.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "reflect" +) + +//Student 学生 +type Students struct { + ID int `json:"id"` //通过指定tag实现json序列化该字段时的key + Gender string //json序列化是默认使用字段名作为key + Name []string //私有不能被json包访问 +} + +type XiaoMing struct { + age int + Students +} + +func main() { + var data *byte + var in interface{} + + fmt.Println(data) + fmt.Println(in) + in = data + + fmt.Println(IsNil(in)) + fmt.Println(in == nil) +} + +func IsNil(i interface{}) bool { + vi := reflect.ValueOf(i) + if vi.Kind() == reflect.Ptr { + return vi.IsNil() + } + return false +} \ No newline at end of file diff --git a/struct/test01.go b/struct/test01.go new file mode 100644 index 0000000..46e6fce --- /dev/null +++ b/struct/test01.go @@ -0,0 +1,26 @@ +package main + +import "fmt" + +type student struct { + id int + name string + age int +} + +func demo(ce []student) { + //切片是引用传递,是可以改变值的 + ce[1].age = 999 + // ce = append(ce, student{3, "xiaowang", 56}) + // return ce +} +func main() { + var ce []student //定义一个切片类型的结构体 + ce = []student{ + student{1, "xiaoming", 22}, + student{2, "xiaozhang", 33}, + } + fmt.Println(ce) + demo(ce) + fmt.Println(ce) +} \ No newline at end of file diff --git a/text.txt b/text.txt new file mode 100644 index 0000000..37039af --- /dev/null +++ b/text.txt @@ -0,0 +1 @@ +sdasdadasdasdasdasd从v现场v下 \ No newline at end of file diff --git a/trace.out b/trace.out new file mode 100644 index 0000000..7085f1c Binary files /dev/null and b/trace.out differ diff --git a/variable/constantTest.go b/variable/constantTest.go new file mode 100644 index 0000000..b9c40a1 --- /dev/null +++ b/variable/constantTest.go @@ -0,0 +1,33 @@ +package main + +import "fmt" + +func printHello(ch chan int) { + fmt.Println("Hello from printHello") + //send a value on channel + ch <- 2 +} +func main() { + //make a channel. You need to use the make function to create channels. + //channels can also be buffered where you can specify size. eg: ch := make(chan int, 2) + //that is out of the scope of this post. + ch := make(chan int) + //inline goroutine. Define a function and then call it. + //write on a channel when done + go func() { + fmt.Println("Hello inline") + //send a value on channel + ch <- 1 + }() + //call a function as goroutine + go printHello(ch) + fmt.Println("Hello from main") + //get first value from channel. + //and assign to a variable to use this value later + //here that is to print it + i := <-ch + fmt.Println("Recieved ", i) + //get the second value from channel + //do not assign it to a variable because we dont want to use that + <-ch +} \ No newline at end of file diff --git a/variable/stringTest.go b/variable/stringTest.go new file mode 100644 index 0000000..d211e0a --- /dev/null +++ b/variable/stringTest.go @@ -0,0 +1,39 @@ +package main + +import "fmt" + +func main() { + //str := "Feyoungg" + //println(len(str)) + //println(strings.Contains(str, "s")) + //println(strings.HasPrefix(str, "F")) + //println(strings.HasSuffix(str, "F")) + //println(strings.Index(str, "g")) + //println(strings.LastIndex(str, "g")) + //arr := [...]struct{ + // name string + // age int + //}{ + // {"user01",10}, + // {"user02",9}, + //} + //fmt.Println(arr) + // + //arr2 := [...][2]int{{1,1},{2,2},{3,3}} + //var arr3 [3][2]int + //fmt.Println(arr2) + //fmt.Println(arr3) + a := [2]int{} + fmt.Printf("a: %p\n",&a) + + a = test(a) + fmt.Println(a) +} + +func test(x [2]int)(y [2]int) { + fmt.Printf("x: %p\n", &x) + x[1] = 1000 + fmt.Println(x) + return x +} + diff --git a/variable/variableTest.go b/variable/variableTest.go new file mode 100644 index 0000000..227f633 --- /dev/null +++ b/variable/variableTest.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func init() { + +} + +func main() { + x, _ := foo() + _, y := foo() + fmt.Println(x) + fmt.Println(y) +} + +func foo() (int, string) { + return 10,"Feyoung" +} +