欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言使用Request,Response處理web頁面請求

 更新時間:2022年04月18日 10:42:19   作者:駿馬金龍  
這篇文章主要介紹了Go語言使用Request,Response處理web頁面請求,需要的朋友可以參考下

Go語言處理web頁面請求

Request和Response

http Requset和Response的內(nèi)容包括以下幾項:

  • Request or response line
  • Zero or more headers
  • An empty line, followed by …
  • … an optional message body

例如一個http Request:

GET /Protocols/rfc2616/rfc2616.html HTTP/1.1
Host: www.w3.org
User-Agent: Mozilla/5.0
(empty line)

如果是POST方法,在empty line后還包含請求體。

一個http Response:

HTTP/1.1 200 OK
Content-type: text/html
Content-length: 24204
(empty line)
and then 24,204 bytes of HTML code

go http包分為兩種角色:http Client和http Server。http Client可以發(fā)送請求,比如寫爬蟲程序時語言扮演的角色就是http Client;http Server用來提供web服務(wù),可以處理http請求并響應(yīng)。

對于Request,作為http客戶端(如編寫爬蟲類工具)常需要關(guān)注的是URL和User-Agent以及其它幾個Header;作為http服務(wù)端(web服務(wù)端,處理請求)常需要關(guān)注的幾項是:

URL
Header
Body
Form,、PostForm、MultipartForm

以下是完整的Request結(jié)構(gòu)以及相關(guān)的函數(shù)、方法:混個眼熟就好了

type Request struct {
        Method string
        URL *url.URL
        Header Header
        Body io.ReadCloser
        GetBody func() (io.ReadCloser, error)  // Server: x, Cleint: √
        ContentLength int64
        TransferEncoding []string
        Close bool                 // Server: x, Cleint: √
        Host string
        Form url.Values
        PostForm url.Values
        MultipartForm *multipart.Form
        Trailer Header
        RemoteAddr string
        RequestURI string           // x
        TLS *tls.ConnectionState
        Cancel <-chan struct{}      // x
        Response *Response          // x
}

func NewRequest(method, url string, body io.Reader) (*Request, error)
func ReadRequest(b *bufio.Reader) (*Request, error)
func (r *Request) AddCookie(c *Cookie)
func (r *Request) BasicAuth() (username, password string, ok bool)
func (r *Request) Context() context.Context
func (r *Request) Cookie(name string) (*Cookie, error)
func (r *Request) Cookies() []*Cookie
func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error)
func (r *Request) FormValue(key string) string
func (r *Request) MultipartReader() (*multipart.Reader, error)
func (r *Request) ParseForm() error
func (r *Request) ParseMultipartForm(maxMemory int64) error
func (r *Request) PostFormValue(key string) string
func (r *Request) ProtoAtLeast(major, minor int) bool
func (r *Request) Referer() string
func (r *Request) SetBasicAuth(username, password string)
func (r *Request) UserAgent() string
func (r *Request) WithContext(ctx context.Context) *Request
func (r *Request) Write(w io.Writer) error
func (r *Request) WriteProxy(w io.Writer) error

注意有哪些字段和方法,字段的詳細說明見go doc http.Request。上面打了"x"的表示不需要了解的或者廢棄的。

有一個特殊的字段Trailer,它是Header類型的,顯然它存放的是一個個請求header,它表示請求發(fā)送完成之后再發(fā)送的額外的header。對于Server來說,讀取了request.Body之后才會讀取Trailer。很少有瀏覽器支持HTTP Trailer功能。

以下是完整的Response結(jié)構(gòu)以及相關(guān)的函數(shù)、方法:混個眼熟就好了

type Response struct {
        Status     string // e.g. "200 OK"
        StatusCode int    // e.g. 200
        Proto      string // e.g. "HTTP/1.0"
        ProtoMajor int    // e.g. 1
        ProtoMinor int    // e.g. 0
        Header Header
        Body io.ReadCloser
        ContentLength int64
        TransferEncoding []string
        Close bool
        Uncompressed bool
        Trailer Header
        Request *Request
        TLS *tls.ConnectionState
}

func Get(url string) (resp *Response, err error)
func Head(url string) (resp *Response, err error)
func Post(url string, contentType string, body io.Reader) (resp *Response, err error)
func PostForm(url string, data url.Values) (resp *Response, err error)
func ReadResponse(r *bufio.Reader, req *Request) (*Response, error)
func (r *Response) Cookies() []*Cookie
func (r *Response) Location() (*url.URL, error)
func (r *Response) ProtoAtLeast(major, minor int) bool
func (r *Response) Write(w io.Writer) error

其實有些直接從字面意思看就知道了。

Http Header

Request和Response結(jié)構(gòu)中都有Header字段,Header是一個map結(jié)構(gòu)。

type Header map[string][]string
    A Header represents the key-value pairs in an HTTP header.

func (h Header) Add(key, value string)
func (h Header) Del(key string)
func (h Header) Get(key string) string
func (h Header) Set(key, value string)
func (h Header) Write(w io.Writer) error
func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error

key是Header字段名,value是Header字段的值,同個字段多個值放在string的slice中。

Add()、Del()、Get()、Set()意義都很明確。

Write()是將Header寫進Writer中,比如從網(wǎng)絡(luò)連接中發(fā)送出去。WriteSubSet()和Write()類似,但可以指定exclude[headerkey]==true排除不寫的字段。

下面是一個示例:

package main

import (
	"fmt"
	"net/http"
)

func headers(w http.ResponseWriter, r *http.Request) {
	for key := range r.Header {
		fmt.Fprintf(w, "%s: %s\n", key, r.Header[key])
	}
	fmt.Fprintf(w, "--------------\n")
	fmt.Fprintf(w, "the key: %s\n", r.Header["Accept-Encoding"])
	fmt.Fprintf(w, "the key: %s\n", r.Header.Get("Accept-Encoding"))
}
func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/headers", headers)
	server.ListenAndServe()
}

瀏覽器中訪問http://127.0.0.1:8080/headers的結(jié)果:

Connection: [keep-alive]
Cache-Control: [max-age=0]
Upgrade-Insecure-Requests: [1]
User-Agent: [Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36]
Accept: [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8]
Accept-Encoding: [gzip, deflate, br]
Accept-Language: [zh-CN,zh;q=0.9,en;q=0.8]
--------------
the key: [gzip, deflate, br]
the key: gzip, deflate, br

Http Body

Request和Response結(jié)構(gòu)中都有Body字段,它們都是io.ReadCloser接口類型。從名字可以看出,io.ReadCloser由兩個接口組成:Reader和Closer,意味著它實現(xiàn)了Reader接口的Read()方法,也實現(xiàn)了Closer接口的Close()方法。這意味著Body的實例可以調(diào)用Read()方法,也可以調(diào)用Close()方法。

例如,下面寫一個handler,從請求中讀取Body并輸出:

package main

import (
	"fmt"
	"net/http"
)

func body(w http.ResponseWriter, r *http.Request) {
	len := r.ContentLength
	body := make([]byte, len)
	r.Body.Read(body)
	fmt.Fprintf(w, "%s\n", string(body))
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/body", body)
	server.ListenAndServe()
}

因為使用HTTP Get方法的Request沒有Body,所以這里使用curl的"-d"選項來構(gòu)造一個POST請求,并發(fā)送Request Body:

$ curl -id "name=lognshuai&age=23" 127.0.0.1:8080/body
HTTP/1.1 200 OK
Date: Mon, 26 Nov 2018 09:04:40 GMT
Content-Length: 22
Content-Type: text/plain; charset=utf-8

name=lognshuai&age=23

Go和HTML Form

在Request結(jié)構(gòu)中,有3個和form有關(guān)的字段:

// Form字段包含了解析后的form數(shù)據(jù),包括URL的query、POST/PUT提交的form數(shù)據(jù)
// 該字段只有在調(diào)用了ParseForm()之后才有數(shù)據(jù)
Form url.Values

// PostForm字段不包含URL的query,只包括POST/PATCH/PUT提交的form數(shù)據(jù)
// 該字段只有在調(diào)用了ParseForm()之后才有數(shù)據(jù)
PostForm url.Values // Go 1.1

// MultipartForm字段包含multipart form的數(shù)據(jù)
// 該字段只有在調(diào)用了ParseMultipartForm()之后才有數(shù)據(jù)
MultipartForm *multipart.Form

所以,一般的邏輯是:

  • 先調(diào)用ParseForm()或ParseMultipartForm()解析請求中的數(shù)據(jù)
  • 按需訪問Request結(jié)構(gòu)中的Form、PostForm或MultipartForm字段

除了先解析再訪問字段的方式,還可以直接使用Request的方法:

  • FormValue(key)
  • PostFormValue(key)

稍后解釋這兩個方法。

取Form和PostForm字段

給定一個html文件,這個html文件里是form表單:

<html>
  <head>    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Go Web</title>
  </head>
  <body>
    <form action=http://127.0.0.1:8080/process?name=xiaofang&boyfriend=longshuai
      method="post" enctype="application/x-www-form-urlencoded">
      <input type="text" name="name" value="longshuai"/>
      <input type="text" name="age" value="23"/>
      <input type="submit"/>
    </form>
  </body>
</html>

在這個form里,action指定了要訪問的url,其中path=process,query包含name和boyfriend兩個key。除此之外,form表單的input屬性里,也定義了name和age兩個key,由于method為post,這兩個key是作為request body發(fā)送的,且因為enctype指定為application/x-www-form-urlencoded,這兩個key會按照URL編碼的格式進行組織。

下面是web handler的代碼:

package main

import (
	"fmt"
	"net/http"
)

func form(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Fprintf(w, "%s\n", r.Form)
	fmt.Fprintf(w, "%s\n", r.PostForm)
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", form)
	server.ListenAndServe()
}

上面先使用ParseForm()方法解析Form,再訪問Request中的Form字段和PostForm字段。

打開前面的Html文件,點擊"提交"后,將輸出:

map[name:[longshuai xiaofang] age:[23] boyfriend:[longshuai]]
map[name:[longshuai] age:[23]]

如果這時,將application/x-www-form-urlencoded改成multipart/form-data,再點擊提交,將輸出:

map[name:[xiaofang] boyfriend:[longshuai]]
map[]

顯然,使用multipart/form-data編碼form的時候,編碼的內(nèi)容沒有放進Form和PostForm字段中,或者說編碼的結(jié)果沒法放進這兩個字段中。

取MultipartForm字段

要取MultipartForm字段的數(shù)據(jù),先使用ParseMultipartForm()方法解析Form,解析時會讀取所有數(shù)據(jù),但需要指定保存在內(nèi)存中的最大字節(jié)數(shù),剩余的字節(jié)數(shù)會保存在臨時磁盤文件中。

package main

import (
	"fmt"
	"net/http"
)

func form(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(1024)
	fmt.Fprintf(w,"%s\n",r.Form)
	fmt.Fprintf(w,"%s\n",r.PostForm)
	fmt.Fprintf(w,"%s\n",r.MultipartForm)

}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", form)
	server.ListenAndServe()
}

將html文件的enctype改為multipart/form-data后,重新點開html文件,將輸出:

map[name:[xiaofang longshuai] boyfriend:[longshuai] age:[23]]
map[name:[longshuai] age:[23]]
&{map[name:[longshuai] age:[23]] map[]}

前兩行結(jié)果意味著ParseMultipartForm()方法也調(diào)用了ParseForm()方法,使得除了設(shè)置MultipartForm字段,也會設(shè)置Form字段和PostForm字段。

注意上面的第三行,返回的是一個struct,這個struct中有兩個map,第一個map是來自form的key/value,第二個map為空,這個見后面的File。

最后還需注意的是,enctype=multipart/form-dataenctype=application/x-www-form-urlencoded時,Request.Form字段中key的保存順序是不一致的:

// application/x-www-form-urlencoded
map[name:[longshuai xiaofang] age:[23] boyfriend:[longshuai]]

// multipart/form-data
map[name:[xiaofang longshuai] boyfriend:[longshuai] age:[23]]

FormValue()和PostFormValue()

前面都是先調(diào)用ParseForm()或ParseMultipartForm()解析Form后再調(diào)用Request中對應(yīng)字段的。還可以直接調(diào)用FormValue()或PostFormValue()方法。

  • FormValue(key)
  • PostFormValue(key)

這兩個方法在需要時會自動調(diào)用ParseForm()或ParseMultipartForm(),所以使用這兩個方法取Form數(shù)據(jù)的時候,可以不用顯式解析Form。

FormValue()返回form數(shù)據(jù)和url query組合后的第一個值。要取得完整的值,還是需要訪問Request.Form或Request.PostForm字段。但因為FormValue()已經(jīng)解析過Form了,所以無需再顯式調(diào)用ParseForm()再訪問request中Form相關(guān)字段。

PostFormValue()返回form數(shù)據(jù)的第一個值,因為它只能訪問form數(shù)據(jù),所以忽略URL的query部分。

先看FormValue()方法的使用。注意,下面調(diào)用了FormValue()之后沒有調(diào)用ParseForm()和ParseMultipartForm()解析Form,就可以直接訪問Request中和Form相關(guān)的3個字段。

package main

import (
	"fmt"
	"net/http"
)

func form(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w,"%s\n",r.FormValue("name"))
	fmt.Fprintf(w,"%s\n",r.FormValue("age"))
	fmt.Fprintf(w,"%s\n",r.FormValue("boyfriend"))
	fmt.Fprintf(w,"%s\n",r.Form)
	fmt.Fprintf(w,"%s\n",r.PostForm)
	fmt.Fprintf(w,"%s\n",r.MultipartForm)
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", form)
	server.ListenAndServe()
}

enctype=multipart/form-data時,會自動調(diào)用ParseMultipartForm(),輸出結(jié)果:

xiaofang
23
longshuai
map[name:[xiaofang longshuai] boyfriend:[longshuai] age:[23]]
map[name:[longshuai] age:[23]]
&{map[name:[longshuai] age:[23]] map[]}

enctype=application/x-www-form-urlencoded時,會自動調(diào)用ParseForm(),輸出結(jié)果:

longshuai
23
longshuai
map[name:[longshuai xiaofang] age:[23] boyfriend:[longshuai]]
map[name:[longshuai] age:[23]]
%!s(*multipart.Form=<nil>)

仍然注意,因為兩種enctype導致的Request.Form存儲key時的順序不一致,使得訪問有多個值的key得到的結(jié)果不一致。

再看PostFormValue()方法的使用。

package main

import (
	"fmt"
	"net/http"
)

func form(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w,"%s\n",r.PostFormValue("name"))
	fmt.Fprintf(w,"%s\n",r.PostFormValue("age"))
	fmt.Fprintf(w,"%s\n",r.PostFormValue("boyfriend"))
	fmt.Fprintf(w,"%s\n",r.Form)
	fmt.Fprintf(w,"%s\n",r.PostForm)
	fmt.Fprintf(w,"%s\n",r.MultipartForm)
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", form)
	server.ListenAndServe()
}

enctype=multipart/form-data時,會自動調(diào)用ParseMultipartForm(),輸出結(jié)果:

longshuai
23

map[name:[xiaofang longshuai] boyfriend:[longshuai] age:[23]]
map[name:[longshuai] age:[23]]
&{map[name:[longshuai] age:[23]] map[]}

enctype=application/x-www-form-urlencoded時,會自動調(diào)用ParseForm(),輸出結(jié)果:

longshuai
23

map[age:[23] boyfriend:[longshuai] name:[longshuai xiaofang]]
map[name:[longshuai] age:[23]]
%!s(*multipart.Form=<nil>)

注意,由于PostFormValue()方法只能訪問form數(shù)據(jù),上面調(diào)用了PostFormValue()后,無法使用PostFormValue()訪問URL中的query的Key/value,盡管request中的字段都合理設(shè)置了。

Files

multipart/form-data最常用的場景可能是上傳文件,比如在form中使用file標簽。以下是html文件:

<html>
  <head>    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Go Web Programming</title>
  </head>
  <body>
    <form action=http://127.0.0.1:8080/process?name=xiaofang&boyfriend=longshuai
      method="post" enctype="multipart/form-data">
      <input type="text" name="name" value="longshuai"/>
      <input type="text" name="age" value="23"/>
      <input type="file" name="file_to_upload">
      <input type="submit"/>
    </form>
  </body>
</html>

下面是服務(wù)端接收上傳文件數(shù)據(jù)的代碼:

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func form(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(1024)
	fileHeader := r.MultipartForm.File["file_to_upload"][0]
	file, err := fileHeader.Open()
	if err == nil {
		dataFromFile, err := ioutil.ReadAll(file)
		if err == nil {
			fmt.Fprintf(w, "%s\n", dataFromFile)
		}
	}
	fmt.Fprintf(w, "%s\n", r.MultipartForm)
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/process", form)
	server.ListenAndServe()
}

上面先調(diào)用ParseMultipartForm()解析multipart form,然后訪問request的MultipartForm字段,這個字段的類型是*multipart.Form,該類型定義在mime/multipart/formdata.go文件中:

$ go doc multipart.Form
package multipart // import "mime/multipart"

type Form struct {
        Value map[string][]string
        File  map[string][]*FileHeader
}

Form類型表示解析后的multipart form,字段File和Value都是map類型的,其中File的map value是*FileHeader類型:

$ go doc multipart.fileheader
package multipart // import "mime/multipart"

type FileHeader struct {
        Filename string
        Header   textproto.MIMEHeader
        Size     int64

        // Has unexported fields.
}
    A FileHeader describes a file part of a multipart request.


func (fh *FileHeader) Open() (File, error)

它實現(xiàn)了Open()方法,所以可以直接調(diào)用Open()來打開multipart.Form的File部分。即:

fileHeader := r.MultipartForm.File["file_to_upload"][0]
file, err := fileHeader.Open()

然后讀取這段數(shù)據(jù),響應(yīng)給客戶端。注意,有了File后,request.MultipartForm字段的第二個map就有了值,第二個map對應(yīng)的就是multipart.Form.File的內(nèi)容。

整個返回結(jié)果如下:

FormFile()

類似于FormValue()和PostFormValue()方法的便捷,讀取multipart.Form也有快捷方式:

$ go doc http.formfile
func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error)
    FormFile returns the first file for the provided form key. FormFile calls
    ParseMultipartForm and ParseForm if necessary.

FormFile()方法會在需要的時候自動調(diào)用parseMultipartForm()或ParseForm()。注意它的返回值。因為第一個返回值為multipart.File,說明至少實現(xiàn)了io.Reader接口,可以直接讀取這個文件。

修改上一節(jié)的示例:

func form(w http.ResponseWriter, r *http.Request) {
	file, _, err := r.FormFile("file_to_upload")

	if err != nil {
		panic(err)
	}
	dataFromFile, err := ioutil.ReadAll(file)
	if err != nil {
		panic(err)
	}
	fmt.Fprintf(w, "%s\n", dataFromFile)
}

ResponseWriter

ResponseWriter接口用于發(fā)送響應(yīng)數(shù)據(jù)、響應(yīng)header。它有3個方法:

type ResponseWriter interface {
    Header() Header
    Write([]byte) (int, error)
    WriteHeader(statusCode int)
}
    A ResponseWriter interface is used by an HTTP handler to construct an HTTP
    response.

    A ResponseWriter may not be used after the Handler.ServeHTTP method has
    returned.

Header()用于構(gòu)造response header,構(gòu)造好的header會在稍后自動被WriteHeader()發(fā)送出去。比如設(shè)置一個Location字段:

w.Header().Set("Location", "http://google.com")

Write()用于發(fā)送響應(yīng)數(shù)據(jù),例如發(fā)送html格式的數(shù)據(jù),json格式的數(shù)據(jù)等。

str := `<html>
<head><title>Go Web Programming</title></head>
<body><h1>Hello World</h1></body>
</html>`
w.Write([]byte(str))

WriteHeader(int)可以接一個數(shù)值HTTP狀態(tài)碼,同時它會將構(gòu)造好的Header自動發(fā)送出去。如果不顯式調(diào)用WriteHeader(),會自動隱式調(diào)用并發(fā)送200 OK。

下面是一個示例:

package main

import (
	"fmt"
	"encoding/json"
	"net/http"
)

func commonWrite(w http.ResponseWriter, r *http.Request) {
	str := `<html>
		<head>
			<title>Go Web</title>
		</head>
		<body>
			<h1>Hello World</h1>
		</body>
	</html>`
	w.Write([]byte(str))
}

func writeHeader(w http.ResponseWriter,r *http.Request){
	w.WriteHeader(501)
	fmt.Fprintln(w,"not implemented service")
}

func header(w http.ResponseWriter,r *http.Request){
	w.Header().Set("Location","http://www.baidu.com")
	w.WriteHeader(302)
}

type User struct {
	Name    string
	Friends []string
}

func jsonWrite(w http.ResponseWriter, r *http.Request) {
	var user = &User{
		Name:    "longshuai",
		Friends: []string{"personA", "personB", "personC"},
	}
	w.Header().Set("Content-Type", "application/json")
	jsonData, _ := json.Marshal(user)
	w.Write(jsonData)
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8080",
	}
	http.HandleFunc("/commonwrite", commonWrite)
	http.HandleFunc("/writeheader", writeHeader)
	http.HandleFunc("/header", header)
	http.HandleFunc("/jsonwrite", jsonWrite)
	server.ListenAndServe()
}

commonWrite()這個handler用于輸出帶html格式的數(shù)據(jù)。訪問結(jié)果:

writeheader()這個handler用于顯式發(fā)送501狀態(tài)碼。訪問結(jié)果:

$ curl -i 127.0.0.1:8080/writeheader
HTTP/1.1 501 Not Implemented
Date: Tue, 27 Nov 2018 03:36:57 GMT
Content-Length: 24
Content-Type: text/plain; charset=utf-8

not implemented service

header()這個handler用于設(shè)置響應(yīng)的Header,這里設(shè)置了302重定向,客戶端收到302狀態(tài)碼后會找Location字段的值,然后重定向到http://www.baidu.com。

jsonWrite()這個handler用于發(fā)送json數(shù)據(jù),所以發(fā)送之前先設(shè)置了Content-Type: application/json。

更多關(guān)于Go語言使用Request,Response處理web頁面請求的方法請查看下面的相關(guān)鏈接

相關(guān)文章

  • go xorm框架的使用

    go xorm框架的使用

    xorm框架和Spring Data Jpa有點相似,可以對比學習,對于這個框架感覺還不錯,閑暇時間學習一下
    2021-05-05
  • Go語言for range(按照鍵值循環(huán))遍歷操作

    Go語言for range(按照鍵值循環(huán))遍歷操作

    這篇文章主要介紹了Go語言for range(按照鍵值循環(huán))遍歷操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • golang如何通過viper讀取config.yaml文件

    golang如何通過viper讀取config.yaml文件

    這篇文章主要介紹了golang通過viper讀取config.yaml文件,圍繞golang讀取config.yaml文件的相關(guān)資料展開詳細內(nèi)容,需要的小伙伴可以參考一下
    2022-03-03
  • GoRoutines高性能同時進行多個Api調(diào)用實現(xiàn)

    GoRoutines高性能同時進行多個Api調(diào)用實現(xiàn)

    這篇文章主要為大家介紹了GoRoutines高性能同時進行多個Api調(diào)用實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • 深入解析快速排序算法的原理及其Go語言版實現(xiàn)

    深入解析快速排序算法的原理及其Go語言版實現(xiàn)

    這篇文章主要介紹了快速排序算法的原理及其Go語言版實現(xiàn),文中對于快速算法的過程和效率有較為詳細的說明,需要的朋友可以參考下
    2016-04-04
  • golang語言實現(xiàn)的文件上傳與文件下載功能示例

    golang語言實現(xiàn)的文件上傳與文件下載功能示例

    這篇文章主要介紹了golang語言實現(xiàn)的文件上傳與文件下載功能,結(jié)合實例形式分析了Go語言實現(xiàn)的文件傳輸相關(guān)操作技巧,需要的朋友可以參考下
    2020-02-02
  • go語言beego框架web開發(fā)語法筆記示例

    go語言beego框架web開發(fā)語法筆記示例

    這篇文章主要為大家介紹了go語言beego框架web開發(fā)語法筆記示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • go語言中的return語句

    go語言中的return語句

    這篇文章主要介紹了go語言中的return語句,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你的學習有所幫助
    2022-05-05
  • golang端口占用檢測的使用

    golang端口占用檢測的使用

    這篇文章主要介紹了golang端口占用檢測的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • golang?gorm的Callbacks事務(wù)回滾對象操作示例

    golang?gorm的Callbacks事務(wù)回滾對象操作示例

    這篇文章主要為大家介紹了golang?gorm的Callbacks事務(wù)回滾對象操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04

最新評論