首页
📷在线壁纸
🎬娱乐天地
🔖友情链接
更多
📝留言板
Search
1
【javascript】JS-向当前url追加参数
2,345 阅读
2
【PHP】生成随机昵称
2,202 阅读
3
【PHP】判断一个字符串是否属于序列化后的数据
2,024 阅读
4
【css】html+css给文章页,做阅读全文
1,975 阅读
5
【PHP】 设计模式(23种)
1,909 阅读
📂默认分类
💓typecho
🏳️🌈代码改变世界
🍇 mysql
🍈 Winform
🍓 golang
🍉 设计模式
🥝 PHP
🍎 python
🍊 nginx
🍋 网络安全
🍍 javascript
🫑 database
🍡 AI
🍭文艺范
🍏mac
登录
Search
标签搜索
php
typecho
代码注释
redis
mysql
go
golang
nginx
thinkphp
docker
gin
linux
curl
html
mamp
算法
短网址
构造函数
webhook
代码片段
依然范儿特西
累计撰写
145
篇文章
累计收到
1
条评论
首页
栏目
📂默认分类
💓typecho
🏳️🌈代码改变世界
🍇 mysql
🍈 Winform
🍓 golang
🍉 设计模式
🥝 PHP
🍎 python
🍊 nginx
🍋 网络安全
🍍 javascript
🫑 database
🍡 AI
🍭文艺范
🍏mac
页面
📷在线壁纸
🎬娱乐天地
🔖友情链接
📝留言板
搜索到
11
篇与
的结果
2024-03-28
golang+VsCode中的代码自动补全和自动导入包
VSCode 必须安装以下插件:首先你必须安装 Golang 插件,然后再给 Go 安装工具包。在 VS Code 中,使用快捷键:command+shift+P,然后键入:go:install/update tools,将所有 16 个插件都勾选上,然后点击 OK 即开始安装。Installing 16 tools at /Users/maiyang/develop/goworkspace//bin gocode gopkgs go-outline go-symbols guru gorename dlv godef godoc goreturns golint gotests gomodifytags impl fillstruct goplay Installing github.com/mdempsky/gocode SUCCEEDED Installing github.com/uudashr/gopkgs/cmd/gopkgs SUCCEEDED Installing github.com/ramya-rao-a/go-outline SUCCEEDED Installing github.com/acroca/go-symbols SUCCEEDED Installing golang.org/x/tools/cmd/guru SUCCEEDED Installing golang.org/x/tools/cmd/gorename SUCCEEDED Installing github.com/derekparker/delve/cmd/dlv SUCCEEDED Installing github.com/rogpeppe/godef SUCCEEDED Installing golang.org/x/tools/cmd/godoc SUCCEEDED Installing github.com/sqs/goreturns SUCCEEDED Installing github.com/golang/lint/golint SUCCEEDED Installing github.com/cweill/gotests/... SUCCEEDED Installing github.com/fatih/gomodifytags SUCCEEDED Installing github.com/josharian/impl SUCCEEDED Installing github.com/davidrjenni/reftools/cmd/fillstruct SUCCEEDED Installing github.com/haya14busa/goplay/cmd/goplay SUCCEEDED All tools successfully installed. You're ready to Go :). 修改默认配置的方法:在 Preferences -> Setting 然后输入 go,然后选择 setting.json,填入你想要修改的配置自动完成未导入的包。 "go.autocompleteUnimportedPackages": true,VSCode 的一些插件需要配置代理,才能够正常安装。 "http.proxy": "192.168.1.110:1088",如果你遇到使用标准包可以出现代码提示,但是使用自己的包或者第三方库无法出现代码提示,你可以查看一下你的配置项。 "go.inferGopath": true,如果引用的包使用了 ( . “aa.com/text”) 那这个text包下的函数也无法跳转进去,这是为什么?修改 "go.docsTool" 为 gogetdoc,默认是 godoc。"go.docsTool": "gogetdoc",其他当我们在使用 import 功能的时候,如果无法通过 lint 检查,则不会执行自动 import。如果你需要自动 import 的前提是你必须把要导入的包的函数写完整。附带我的 settings.json{ "go.goroot": "", "go.gopath": "", "go.inferGopath": true, "go.autocompleteUnimportedPackages": true, "go.gocodePackageLookupMode": "go", "go.gotoSymbol.includeImports": true, "go.useCodeSnippetsOnFunctionSuggest": true, "go.useCodeSnippetsOnFunctionSuggestWithoutType": true, "go.docsTool": "gogetdoc", }
2024年03月28日
7 阅读
0 评论
0 点赞
2024-02-28
golang 编程规范 - 项目目录结构
参考链接 https://makeoptim.com/golang/standards/project-layout#google_vignette针对API使用的目录结构, 如果有用作其他服务,可以灵活调整 ├── api (项目对外提供和依赖的 API 文件) │ └── dao │ └── http │ └── v1 │ └── v2 │ └── middleware │ └── model │ └── router │ └── service │ └── validator │ ├── cmd (当前项目的可执行文件) │ └── ├── internal (私有的应用程序代码库) │ └── ├── configs (配置文件和初始化文件) │ └── ├── global (全局变量) │ └── ├── deploy (IaaS,PaaS,系统和容器编排部署配置和模板) │ └── ├── pkg (外部应用程序可以使用的库代码) │ └── ├── scripts (用于执行各种构建,安装,分析等操作的脚本) │ └── ├── third_parth (外部辅助工具) │ └── ├── test (单元测试) │ └── ├── vendor (应用程序的依赖关系) │ └──
2024年02月28日
19 阅读
0 评论
1 点赞
2024-02-28
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
在学习Golang中的gin框架的时候,遇到了下面的warning :[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.对于上面的WARNING翻译出来之后也就是 : 您信任所有代理,这是不安全的。我们建议您设置一个值。对于Goland编译器给出的建议 :Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all- proxies for details.也就是去看文档去了解细节,额,好像又啥也没说!那么怎么解决呢?根据warning也就是给gin设置一个信任ip : 127.0.0.1代码 :router := gin.Default() router.SetTrustedProxies([]string{"127.0.0.1"})
2024年02月28日
1 阅读
0 评论
1 点赞
2023-10-10
Gin 框架在中间件中获取 response body 的方法
在写一个Gin框架日志中间件的时候,需要记录请求和响应相关的一些数据,例如请求参数、请求方法、请求时间、请求头、耗时、响应状态码、响应数据等,gin为获取这些数据基本都提供了现成的方法,但是获取响应数据还是有一定难度和复杂度的。那么,该如何获取响应数据也就是 response body 呢?先上代码。代码示例1、先写一个 middleware ,简单打印一下 response bodypackage middleware import ( "bytes" "fmt" "github.com/gin-gonic/gin" ) //自定义一个结构体,实现 gin.ResponseWriter interface type responseWriter struct { gin.ResponseWriter b *bytes.Buffer } //重写 Write([]byte) (int, error) 方法 func (w responseWriter) Write(b []byte) (int, error) { //向一个bytes.buffer中写一份数据来为获取body使用 w.b.Write(b) //完成gin.Context.Writer.Write()原有功能 return w.ResponseWriter.Write(b) } func PrintResponse(c *gin.Context) { writer := responseWriter{ c.Writer, bytes.NewBuffer([]byte{}), } c.Writer = writer c.Next() fmt.Println("response body:" + writer.b.String()) } 2、引用 middleware ,看看效果package main import ( "github.com/gin-gonic/gin" "hello/middleware" "net/http" ) func main() { r := gin.New() //添加获取响应内容 middleware r.Use(middleware.PrintResponse) r.GET("/test", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"name": "laofan"}) }) // Listen and Server in 0.0.0.0:8080 r.Run(":8080") } 打开浏览器访问http://127.0.0.1:8080/test ,即可在控制台中看到 response body 的输出内容response body:{"name":"laofan"}原理通过上面的代码可以看出,gin 通过调用如下方法写入了 response bodyc.JSON(http.StatusOK, gin.H{"name": "laofan"})追进 JSON 方法,源码如下,调用了 Render 方法package gin func (c *Context) JSON(code int, obj interface{}) { c.Render(code, render.JSON{Data: obj}) }追进 Render 方法, 可以看出 gin.Context.Writer 作为参数传给了 r.Render() 方法,这里形参 r 的实参为 render.JSON{Data: obj} ,所以实际调用的是 func (r JSON) Render(w http.ResponseWriter) 方法。package gin // Render writes the response headers and calls render.Render to render data. func (c *Context) Render(code int, r render.Render) { c.Status(code) if !bodyAllowedForStatus(code) { r.WriteContentType(c.Writer) c.Writer.WriteHeaderNow() return } if err := r.Render(c.Writer); err != nil { panic(err) } } func (r JSON) Render(w http.ResponseWriter) 源码如下package render // Render (JSON) writes data with custom ContentType. func (r JSON) Render(w http.ResponseWriter) (err error) { if err = WriteJSON(w, r.Data); err != nil { panic(err) } return } // WriteJSON marshals the given interface object and writes it with custom ContentType. func WriteJSON(w http.ResponseWriter, obj interface{}) error { writeContentType(w, jsonContentType) jsonBytes, err := json.Marshal(obj) if err != nil { return err } _, err = w.Write(jsonBytes) return err } 在 func (r JSON) Render() 方法中,gin.Context.Writer 被传到了 WriteJSON() 方法中,最终写入数据调用的是 gin.Context.Writer.Write() 方法。gin.ResponseWriter 源码如下package gin type Context struct { //... writermem responseWriter Writer ResponseWriter //... } // ResponseWriter ... type ResponseWriter interface { //... http.ResponseWriter //... } 可以看出 gin.Context.Writer 类型为 interface gin.ResponseWriter。package http type ResponseWriter interface { //... Write([]byte) (int, error) //... } 要实现 gin.ResponseWriter 接口,必须实现Write([]byte) (int, error) 方法。所以写入 response body 调用的是 gin.Context.Writer.Write() 方法,gin.Context.Writer 需要是type gin.ResponseWriter interface 的一个具体实现。到此,可以看出上面代码示例的思路:实现 type gin.ResponseWriter interface 并重写 Write([]byte) (int, error) 方法,该方法在实现 gin.Context.Writer.Write() 原有功能的同时,再向一个 bytes.buffer 中写一份数据来用于获取 response body 使用。
2023年10月10日
5 阅读
0 评论
0 点赞
2022-11-28
golang字符串切割
//定义一个字符串和相应map str := "PHP 是 世 界 上 最 好 的 编 程 语 言" map1 := make(map[string]int) //进行切割,此处成为[]string,并进行排序,方便后面直接计数 str2 := strings.Split(str, " ") sort.Strings(str2) for i := 0; i < len(str2); i++ { count := 1 for j := i + 1; j < len(str2); j++ { if str2[j] == str2[i] { count++ i = j } } map1[str2[i]] = count } fmt.Println(map1)
2022年11月28日
34 阅读
0 评论
0 点赞
2021-11-24
Golang 实现结构体数组按多字段排序
php 排序写法近期因项目重构(php->golang),涉及到一些将对象列表中的对象按不同的字段(属性)排序;在 php 中,可以使用 usort + 自定义的排序函数轻松实现;PHP usort 官方文档下面我们先看一个在 php 中的例子: 下面是一个待排序待数组<?php $result = array( array( "val" => "f", "mtime" => 1595144638, "orderval"=>4 ), array( "val" => "d", "mtime" => 1595144646, "orderval"=>2 ), array( "val" => "a", "mtime" => 1595144648, "orderval"=>8 ), array( "val" => "t", "mtime" => 1595144648, "orderval"=>5 ), array( "val" => "e", "mtime" => 1595144650, "orderval"=>3 ) );我们目前待目标是将该数组中待对象按 mtime 从大到小排序;如果 mtime 字段的值相等,则按 orderval 从大到小排,最终想要的结果为:e,a,t,d,f[ {"val"=>"e","mtime"=>1595144650,"orderval"=>3}, {"val"=>"a","mtime"=>1595144648,"orderval"=>8}, {"val"=>"t","mtime"=>1595144648,"orderval"=>5}, {"val"=>"d","mtime"=>1595144646,"orderval"=>2}, {"val"=>"f","mtime"=>1595144638,"orderval"=>4} ] 我们首先定义一个自定义函数,然后巧妙使用 usort 函数去调用的自定义函数,最终实现目标,直接上代码:php $result = array( array( "val" => "f", "mtime" => 1595144638, "orderval"=>4 ), array( "val" => "d", "mtime" => 1595144646, "orderval"=>2 ), array( "val" => "a", "mtime" => 1595144648, "orderval"=>8 ), array( "val" => "t", "mtime" => 1595144648, "orderval"=>5 ), array( "val" => "e", "mtime" => 1595144650, "orderval"=>3 ) ); //按mtime 从大到小;如果mtime 相等,则按orderval 从大到小; usort($result, function ($v1, $v2) { if ($v1['mtime'] < $v2['mtime'] || ($v1['mtime'] == $v2['mtime'] && $v1['orderval'] < $v2['orderval'])) { return 1; } else { return -1; } }); var_dump($result); 运行结果:array(5) { [0]=> array(3) { ["val"]=> string(1) "e" ["mtime"]=> int(1595144650) ["orderval"]=> int(3) } [1]=> array(3) { ["val"]=> string(1) "a" ["mtime"]=> int(1595144648) ["orderval"]=> int(8) } [2]=> array(3) { ["val"]=> string(1) "t" ["mtime"]=> int(1595144648) ["orderval"]=> int(5) } [3]=> array(3) { ["val"]=> string(1) "d" ["mtime"]=> int(1595144646) ["orderval"]=> int(2) } [4]=> array(3) { ["val"]=> string(1) "f" ["mtime"]=> int(1595144638) ["orderval"]=> int(4) } }那么同样的功能,如果要用 golang 来实现,应如何办呢?golang 排序下面我们首先讲讲 golang 官方对排序 对支持,然后给出具体对例子;package main import ( "fmt" "sort" ) type Obj struct { Var string `json:"var"` Mtime int `json:"mtime"` Orderval int `json:"orderval"` } type List []Obj func (p List) Len() int { return len(p) } // 此处排序是从大到小的, 如果想升序,可以把此方法里的 判定 改为 相反的判定即可 func (p List) Less(i, j int) bool { if p[i].Mtime > p[j].Mtime { return true } if p[i].Mtime < p[j].Mtime { return false } return p[i].Orderval > p[j].Orderval } func (p List) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p *List) Sort() { sort.Sort(p) } func main() { s := List{{"f", 1595144638, 4}, {"d", 1595144646, 2}, {"a", 1595144648, 8}, {"t", 1595144648, 5}, {"e", 1595144650, 3}} fmt.Println(s) s.Sort() fmt.Println(s) } // 如果想使用传入的方法来写,可以把main 方法 的写法改为下边这个 //func toSortAsc(UserList []Obj)[]Obj{ // s := List{} // for _,v := range UserList{ // s = append(s,v) // } // s.Sort() // return s //} 再举一个简单的例子package main import ( "fmt" "sort" ) type Instance struct { Domain string `json:"domain"` Ip string `json:"ip"` Containers []string `json:"containers,omitempty"` } func main() { instances := make([]*Instance, 0, 10) i1 := &Instance{} i1.Domain = "zhap" i1.Ip = "1" instances = append(instances, i1) i2 := &Instance{} i2.Domain = "abc" i2.Ip = "2" instances = append(instances, i2) i3 := &Instance{} i3.Domain = "mid" i3.Ip = "3" instances = append(instances, i3) fmt.Println("排序前 ") for _, v := range instances { fmt.Println(*v) } sort.Slice(instances, func(i, j int) bool { return instances[i].Domain < instances[j].Domain }) fmt.Println("排序后 ") for _, v := range instances { fmt.Println(*v) } }
2021年11月24日
740 阅读
0 评论
2 点赞
2021-11-19
golang 接收命令行参数
方式一package main import ( "fmt" "os" ) func main() { fmt.Println("命令行的参数有", len(os.Args)) // 遍历 os.Args 切片,就可以得到所有的命令行输入参数值 for i, v := range os.Args { fmt.Printf("args[%v]=%v\n", i, v) } }执行结果> go run ./main.go laofan 123 456 789 命令行的参数有 5 args[0]=Temp\go-build\b001\exe\main.exe args[1]=laofan args[2]=123 args[3]=456 args[4]=789 >方式二如像 mysql 那样:mysql -u root -p 123456,可以指定输入内容,输入顺序可变。flag包实现了命令行参数的解析:package main import ( "flag" "fmt" ) func main() { // 定义几个变量,用于接收命令行的参数值 var user string var password string var host string var port int // &user 就是接收命令行中输入 -u 后面的参数值,其他同理 flag.StringVar(&user, "u", "root", "账号,默认为root") flag.StringVar(&password, "p", "", "密码,默认为空") flag.StringVar(&host, "h", "localhost", "主机名,默认为localhost") flag.IntVar(&port, "P", 3306, "端口号,默认为3306") // 解析命令行参数写入注册的flag里 flag.Parse() // 输出结果 fmt.Printf("user:%v\npassword:%v\nhost:%v\nport:%v\n", user, password, host, port) } 执行结果> go run ./main.go -p 123 -u laofan -P 3306 -h 127.0.0.1 user:laofan password:123 host:127.0.0.1 port:3306 > 方式二的另一种写法 package main import ( "flag" "fmt" ) func main () { //获取命令参数 Act := flag.String("act", "", "is ok") date := flag.String("date", "", "id") // 解析命令行参数写入注册的flag里 flag.Parse() fmt.Println("act :", *Act) fmt.Println("date :", *date) }访问结果> go run ./main.go -act laofan -date today act : laofan date : today >
2021年11月19日
162 阅读
0 评论
2 点赞
2021-10-25
GoDoc的使用
一. 约定注释符//后面要加空格, 例如: // xxx在 package, const, type, func等关键字上面并且紧邻关键字的注释才会被展示// 此行注释被省略 // 此行注释被展示 // // 此行注释被展示2 package bananatype, const, func以名称为注释的开头, package以Package name为注释的开头// Package banana ... package banana // Xyz ... const Xyz = 1 // Abc ... type Abc struct {} // Bcd ... func Bcd() {}有效的关键字注释不应该超过3行// Package banana ... // ... // ... // 最好不要超过三行 package bananaPackage的注释如果超过3行, 应该放在当前包目录下一个单独的文件中, 如:doc.go如果当前包目录下包含多个Package注释的go文件(包括doc.go), 那么按照文件名的字母数序优先显示//----- doc.go ----- /* ...第一个显示 */ package banana//----- e.go ----- // Package banana ...第二个显示 package banana//----- f.go ----- // Package banana ...第三个显示 package bananaPackage的注释会出现在godoc的包列表中, 但只能展示大约523字节的长度在无效注释中以BUG(who)开头的注释, 将被识别为已知bug, 显示在bugs区域, 示例// BUG(who): 我是bug说明 // Package banana ... package banana9.如果bug注释和关键字注释中间无换行, 那么混合的注释将被显示在bugs和godoc列表两个区域内// BUG(who): 我是bug注释 // Package banana ...也是pkg注释 package banana段落:/* abc ... bcd Basic(字体加粗变蓝需首字母大写, 中文加粗变蓝需要加上一个大写字母) abc ... ... 属于Basic的段落 ... bcd */ package banana预格式化:/* abc ... bcd Abc(不会加粗变蓝, 预格式化和段落不能同时存在) abc ... 预格式化需要缩进 ... bcd */12.URL将被转化为HTML链接二. Example文件必须放在当前包下文件名以example开头, _连接, test结尾, 如:example_xxx_test.go包名是当前包名 + _test, 如: strings_test函数名称的格式func ExampleFuncName()函数注释会展示在页面上函数结尾加上// Output:注释, 说明函数返回的值// 文件必须放在 banana包目录下, 名字必须为example_xxx_test.go // Package banana_test 为banana包的示例 package banana_test // 此注释将会被展示在页面上 // 此函数将被展示在OverView区域 func Example() { fmt.Println("Hello OverView") // Output: // Hello OverView } // 此函数将被展示在OverView区域, 并展示noOutput标签 func Example_noOutput() { fmt.Println("Hello OverView") // (Output: )非必须, 存在时将会展示输出结果 } // 此函数将被展示在Function区域 // Peel必须是banana包实现的方法 func ExamplePeel() { fmt.Println("Hello Banana") // Output: // Hello Banana } // 此函数将被展示在Function区域 // Peel必须是banana包实现的方法, 并展示big标签 func ExamplePeel_big() { fmt.Println("Hello Banana") // Output: // Hello Banana } 三. Command line安装 godocgo get -v golang.org/x/tools/cmd/godoc开启一个godoc小型server,# 6060是godoc提供的默认端口 # 方式一 godoc -http=:6060 # 方式二 : -play可以使用playground运行Example代码 godoc -http=:6060 -play 查看自己的项目文档# mygoweb 为自己项目的mod里的名字 http://127.0.0.1:6060/pkg/mygoweb/
2021年10月25日
167 阅读
0 评论
1 点赞
2021-10-18
Golang 语言极简 HTTP 客户端 GoRequest
1 介绍GoRequest 是一个极简的 HTTP 客户端,作者灵感来源于 Node.js 库 SuperAgent。相比 Golang 标准库 net/http,GoRequest 使用起来更加简单。GoRequest 官方的口号是 “像机枪一样发送请求”。GoRequest 包含以下功能:支持 HTTP 请求方式:Get/Post/Put/Head/Delete/Patch/Options支持设置 header 请求头支持使用 JSON 字符串作为请求参数支持将多路请求的方式发送数据和文件支持通过代理发送请求支持为请求设置超时支持 TLS 客户端设置支持设置重定向策略支持为请求设置 cookieCookieJar - automatic in-memory cookiejar支持请求头设置基本身份认证安装方式:go get github.com/parnurzeal/gorequest2 HTTP请求方式Golang 发送一个简单的 Get 请求,使用 net/http 标准库和使用 GoRequst 库,两种发送 Get 请求的方式都比较简单。示例代码如下:标准库方式:resp, err := http.Get("http://example.com/")GoRequest 库方式:request := gorequest.New() resp, body, errs := request.Get("http://example.com/").End()或(该 GoRequest 方式无法复用对象)resp, body, errs := gorequest.New().Get("http://example.com/").End()阅读上面这两段代码,我们可以发现,使用标准库的方式发送 Get 请求,甚至比使用 GoRequest 库的方式发送 Get 请求更加简单。但是,当我们需求稍作修改,比如我们需要为 Get 请求,设置 header 头和设置重定向策略。我们再来看一下分别使用标准库和 GoRequest 库两种实现方式。标准库方式:client := &http.Client{ CheckRedirect: redirectPolicyFunc, } req, err := http.NewRequest("GET", "http://example.com", nil) req.Header.Add("If-None-Match", `W/"wyzzy"`) resp, err := client.Do(req)GoRequest 库方式(其它 HTTP 请求方式与 Get 使用方式相同):request := gorequest.New() resp, body, errs := request.Get("http://example.com"). RedirectPolicy(redirectPolicyFunc). Set("If-None-Match", `W/"wyzzy"`). End()阅读上面两段代码,很容易发现使用 GoRequest 方式使实现更加简单。使用标准库方式,首先需要创建一个 Client,然后使用不同的命令设置 header 头等操作,这仅仅是为了实现一个 HTTP 请求。而使用 GoRequest 方式,仅需链式调用两个方法即可轻松实现。3 JSON 格式请求参数在 Golang 语言中,如果使用标准库 net/http 发送请求参数为 JSON 格式的 POST 请求,首先需要先将 map 或 struct 类型的数据,使用标准库 encoding/json 的 Marshal 方法,将数据转换为 JSON 格式的数据,并且设置 header 头参数 Content-Type 的值为 application/json,然后创建一个 Client,最终你的代码变得越来越长,越来越难维护。标准库方式:m := map[string]interface{}{ "name": "backy", "species": "dog", } mJson, _ := json.Marshal(m) contentReader := bytes.NewReader(mJson) req, _ := http.NewRequest("POST", "http://example.com", contentReader) req.Header.Set("Content-Type", "application/json") req.Header.Set("Notes","GoRequest is coming!") client := &http.Client{} resp, _ := client.Do(req)如果使用 GoRequest 库发送请求参数为 JSON 格式的 POST 请求,因为它默认支持 JSON 格式的请求参数,所以它只需要一行代码就可以实现。GoRequest 库方式:request := gorequest.New() resp, body, errs := request.Post("http://example.com"). Set("Notes","gorequst is coming!"). Send(`{"name":"backy", "species":"dog"}`). End()4支持回调函数 CallbackGoRequest 库还支持回调函数,你可以根据自己的项目需求灵活使用它,回调函数示例代码如下:func printStatus(resp gorequest.Response, body string, errs []error){ fmt.Println(resp.Status) } gorequest.New().Get("http://example.com").End(printStatus)5 请求控制在 Golang 项目开发中,有时我们可能需要对请求做一些额外控制,比如超时处理,重试请求 N 次,重定向处理等。GoRequest 库都可以为我们提供简单的实现方式。超时处理:request := gorequest.New().Timeout(2*time.Millisecond) resp, body, errs:= request.Get("http://example.com").End()需要注意的是,Timeout 是将 Dial 连接和 IO 读写的耗时总和,与时间参数作比较。重试请求:request := gorequest.New() resp, body, errs := request.Get("http://example.com/"). Retry(3, 5 * time.Second, http.StatusBadRequest, http.StatusInternalServerError). End()阅读上面这段代码,它的含义是当服务器返回结果是 http.StatusBadRequest 或 http.StatusInternalServerError 时,会每隔 5 秒重试请求一次,共重试 3 次。重定向处理:request := gorequest.New() resp, body, errs := request.Get("http://example.com/"). RedirectPolicy(func(req Request, via []*Request) error { if req.URL.Scheme != "https" { return http.ErrUseLastResponse } }). End() 阅读上面这段代码,它的含义是将 http 请求重定向为 https 请求。6 返回结果处理方式朋友们可能已经发现,以上示例代码都是以 End 结束,End 的含义是返回结果是字符串类型,如果我们希望返回结果是其他类型,比如字节类型和结构体类型,可以将 End 分别替换为 EndBytes 和 EndStruct。EndBytes 格式:resp, bodyBytes, errs := gorequest.New().Get("http://example.com/").EndBytes()EndStruct 格式:heyYou struct { Hey string `json:"hey"` } var heyYou heyYou resp, _, errs := gorequest.New().Get("http://example.com/").EndStruct(&heyYou)7 总结本文我们介绍 Golang 语言的极简 HTTP 客户端 GoRequest 以及它的使用方法。它比标准库 net/http 使用方式简单,当我们项目开发中需要使用 HTTP 方式调用接口时,强烈推荐使用 GoRequest 库。GoRequest 底层在大多数用例中是基于 http.Client 实现的,所以通过一次调用 gorequest.New() 得到的对象,应尽可能多次使用。GoRequest 除了上面介绍的 JSON 参数,它还支持 Struct 和 File,感兴趣的读者可以查阅官方文档了解相关内容。https://github.com/parnurzeal/gorequest
2021年10月18日
261 阅读
0 评论
1 点赞
2021-09-30
Golang之log(如何将日志写到指定文件里面)
对于Go语言的日志来说,如何将log写到指定的文件里面,下面是一个例子。如何将log 写入到指定的文件中?方法一:package main import ( "log" "os" "time" ) func init() { file := "./" +"log"+ ".txt" logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766) if err != nil { panic(err) } log.SetOutput(logFile) // 将文件设置为log输出的文件 log.SetPrefix("[logTool]") log.SetFlags(log.LstdFlags | log.Lshortfile | log.LUTC) return } func main() { log.Println("Hello laofan!") // log 还是可以作为输出的前缀 return }output:// message.txt里面 显示 [logTool]2021/09/30 15:30:05 log.go:24: Hello laofan! 方法二:package main import ( "log" "os" "time" ) var loger *log.Logger func init() { file := "./" + time.Now().Format("20210930") + ".txt" logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766) if err != nil { panic(err) } loger = log.New(logFile, "[logTool]",log.LstdFlags | log.Lshortfile | log.LUTC) // 将文件设置为loger作为输出 return } func main() { // 使用的时候,需要采用loger作为输出的前缀 loger.Println("Hello:laofan!") return } output:// message.txt里面 显示 [logTool]2021/09/30 15:35:20 log.go:24: Hello laofan! `` 灰子作于二零二一年九月三十日。
2021年09月30日
827 阅读
0 评论
0 点赞
1
2