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"
+}
+