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

超詳細(xì)Go語言中JSON處理技巧分享

 更新時間:2023年06月05日 08:41:41   作者:Go學(xué)堂  
這篇文章主要為大家總結(jié)了go語言中對JSON數(shù)據(jù)結(jié)構(gòu)和結(jié)構(gòu)體之間相互轉(zhuǎn)換問題及解決方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

基礎(chǔ)使用

使用Go標(biāo)準(zhǔn)庫中的 json.Marshal()json.Unmarshal進(jìn)行基本的序列化和反序列化。

type Person struct {
	Name   string
	Age    int64
	Weight float64
}
func main() {
	p1 := Person{
		Name:   "Go學(xué)堂",
		Age:    18,
		Weight: 71.5,
	}
	// 將結(jié)構(gòu)體轉(zhuǎn)換成json串
	b, _ := json.Marshal(p1)
	fmt.Printf("str:%s\n", b)
	// 將json串轉(zhuǎn)換成結(jié)構(gòu)體
	var p2 Person
	json.Unmarshal(b, &p2)
	fmt.Printf("p2:%#v\n", p2)
}

輸出:

str:{"Name":"Go學(xué)堂","Age":18,"Weight":71.5}

p2:main.Person{Name:"Go學(xué)堂", Age:18, Weight:71.5}

給結(jié)構(gòu)體指定tag屬性

Tag是結(jié)構(gòu)體的元信息,可以在運(yùn)行的時候通過反射的機(jī)制讀取出來。 Tag在結(jié)構(gòu)體字段的后方定義,由一對**反引號 ****``**包裹起來,具體的格式如Name字段:

type Person struct {
	Name   string `json:"name"`
	Age    int64
	Weight float64
}

這里的json:"name"就是給Name字段的設(shè)置的tag。

tag由一個或多個鍵值對組成。鍵與值使用冒號分隔,值用雙引號括起來。同一個結(jié)構(gòu)體字段可以設(shè)置多個鍵值對tag,不同的鍵值對之間使用空格分隔。如下:

type Person struct {
	Name   string `json:"name" param:"name"`
	Age    int64
	Weight float64
}

使用json tag指定字段名

序列化與反序列化默認(rèn)情況下使用結(jié)構(gòu)體的字段名,我們可以通過給結(jié)構(gòu)體字段添加tag來指定json序列化生成的字段名。

// 使用json tag指定序列化與反序列化時的行為
type Person struct {
	Name   string `json:"name"` // 指定json序列化/反序列化時使用小寫name
	Age    int64
	Weight float64
}

忽略某個字段

如果你想在json序列化/反序列化的時候忽略掉結(jié)構(gòu)體中的某個字段,可以按如下方式在tag中添加**-**。如下Person中的Weight字段

// 使用json tag指定json序列化與反序列化時的行為
type Person struct {
	Name   string `json:"name"` // 指定json序列化/反序列化時使用小寫name
	Age    int64
	Weight float64 `json:"-"` // 指定json序列化/反序列化時忽略此字段
}

忽略空值字段

當(dāng) struct 中的字段沒有值時, json.Marshal() 序列化的時候不會忽略這些字段,而是默認(rèn)輸出字段的類型零值(例如int和float類型零值是 0,string類型零值是"",對象類型零值是 nil)。

如果想要在序列序列化時忽略這些沒有值的字段時,可以在對應(yīng)字段添加**omitempty**** tag**。

將空值輸出的例子

下面是將EmailHobby字段的空值輸出的例子:

type User struct {
	Name  string   `json:"name"`
	Email string   `json:"email"`
	Hobby []string `json:"hobby"`
}
func omitemptyDemo() {
	u1 := User{
		Name: "Go學(xué)堂",
	}
	// struct -> json string
	b, _ := json.Marshal(u1)
	fmt.Printf("str:%s\n", b)
}

輸出結(jié)果:

str:{"name":"Go學(xué)堂","email":"","hobby":null}

將空值忽略的例子

如果想要在最終的序列化結(jié)果中去掉空值字段,可以像下面這樣定義結(jié)構(gòu)體,在Email和Hobby的tag中添加omitempty,以表示若字段值為零值,則在序列化時忽略該字段

// 在tag中添加omitempty忽略空值
// 注意這里 hobby,omitempty 合起來是json tag值,中間用英文逗號分隔
type User struct {
	Name  string   `json:"name"`
	Email string   `json:"email,omitempty"`
	Hobby []string `json:"hobby,omitempty"`
}

此時,再執(zhí)行上述的程序,輸出結(jié)果如下:

str:{"name":"Go學(xué)堂"} // 序列化結(jié)果中沒有email和hobby字段

忽略嵌套結(jié)構(gòu)體空值字段

結(jié)構(gòu)體嵌套可分匿名結(jié)構(gòu)體嵌套具名嵌套。這兩種方式在進(jìn)行json序列化時的行為會有所不同。下面通過示例來說明。

匿名嵌套

匿名嵌套是指在結(jié)構(gòu)體中不指定字段名,只指定類型的字段。匿名嵌套在json序列化時,會直接輸出類型對應(yīng)的字段。如下

type User struct {
	Name  string   `json:"name"`
	Email string   `json:"email,omitempty"`
	Hobby []string `json:"hobby,omitempty"`
	Profile
}
type Profile struct {
	Website string `json:"site"`
	Slogan  string `json:"slogan"`
}
func nestedStructDemo() {
	u1 := User{
		Name:  "Go學(xué)堂",
		Hobby: []string{"足球", "雙色球"},
	}
	b, _ := json.Marshal(u1)
	fmt.Printf("str:%s\n", b)
}

匿名嵌套Profile時序列化后的json串為單層的:

str:{"name":"Go學(xué)堂","hobby":["足球","雙色球"],"site":"","slogan":""}

具名嵌套

想要變成嵌套的json串,需要改為具名嵌套或定義字段tag

type User struct {
	Name    string   `json:"name"`
	Email   string   `json:"email,omitempty"`
	Hobby   []string `json:"hobby,omitempty"`
	Profile `json:"profile"`
}
// str:{"name":"Go學(xué)堂","hobby":["足球","雙色球"],"profile":{"site":"","slogan":""}}

想要在嵌套的結(jié)構(gòu)體為空值時,忽略該字段,僅添加**omitempty**是不夠的

type User struct {
	Name     string   `json:"name"`
	Email    string   `json:"email,omitempty"`
	Hobby    []string `json:"hobby,omitempty"`
	Profile `json:"profile,omitempty"`
}
// str:{"name":"Go學(xué)堂","hobby":["足球","雙色球"],"profile":{"site":"","slogan":""}}

還需要使用嵌套的結(jié)構(gòu)體指針

type User struct {
	Name     string   `json:"name"`
	Email    string   `json:"email,omitempty"`
	Hobby    []string `json:"hobby,omitempty"`
	*Profile `json:"profile,omitempty"`
}
// str:{"name":"Go學(xué)堂","hobby":["足球","雙色球"]}

不修改原結(jié)構(gòu)體,忽略空值字段

我們需要json序列化User,但是不想把密碼也序列化,又不想修改User結(jié)構(gòu)體,這個時候我們就可以使用創(chuàng)建另外一個結(jié)構(gòu)體PublicUser匿名嵌套原User,同時指定Password字段為匿名結(jié)構(gòu)體指針類型,并添加**omitempty **tag,示例代碼如下:

type User struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}
type PublicUser struct {
	*User             // 匿名嵌套
	Password *struct{} `json:"password,omitempty"`
}
func omitPasswordDemo() {
	u1 := User{
		Name:     "Go學(xué)堂",
		Password: "123456",
	}
	b, _ := json.Marshal(PublicUser{User: &u1})
	fmt.Printf("str:%s\n", b)  // str:{"name":"Go學(xué)堂"}
}

優(yōu)雅處理字符串格式的數(shù)字

有時候,前端在傳遞來的json數(shù)據(jù)中可能會使用字符串類型的數(shù)字,這個時候可以在結(jié)構(gòu)體tag中添加string來告訴json包從字符串中解析相應(yīng)字段的數(shù)據(jù)

type Card struct {
	ID    int64   `json:"id,string"`    // 添加string tag
	Score float64 `json:"score,string"` // 添加string tag
}
func intAndStringDemo() {
	jsonStr1 := `{"id": "1234567","score": "88.50"}`
	var c1 Card
	if err := json.Unmarshal([]byte(jsonStr1), &c1); err != nil {
		fmt.Printf("json.Unmarsha jsonStr1 failed, err:%v\n", err)
		return
	}
	fmt.Printf("c1:%#v\n", c1) // c1:main.Card{ID:1234567, Score:88.5}
}

整數(shù)變浮點數(shù)

在 JSON 協(xié)議中是沒有整型和浮點型之分的,它們統(tǒng)稱為number。json字符串中的數(shù)字經(jīng)過Go語言中的json包反序列化之后都會成為float64類型。下面的代碼便演示了這個問題:

func jsonDemo() {
	// map[string]interface{} -> json string
	var m = make(map[string]interface{}, 1)
	m["count"] = 1 // int
	b, _ := json.Marshal(m)
	fmt.Printf("str:%#v\n", string(b))
	// json string -> map[string]interface{}
	var m2 map[string]interface{}
	json.Unmarshal(b, &m2)
	fmt.Printf("value:%v\n", m2["count"]) // 1
	fmt.Printf("type:%T\n", m2["count"])  // float64
}

你看,原本m["count"]的值是整型1,但經(jīng)過序列化和再反序列化后就變成了float64類型了。

這種場景下如果想更合理的處理數(shù)字就需要使用decoder去反序列化,示例代碼如下:

func decoderDemo() {
	// map[string]interface{} -> json string
	var m = make(map[string]interface{}, 1)
	m["count"] = 1 // int
	b, _ := json.Marshal(m)
	fmt.Printf("str:%#v\n", string(b))
	// json string -> map[string]interface{}
	var m2 map[string]interface{}
	// 使用decoder方式反序列化,指定使用number類型
	decoder := json.NewDecoder(bytes.NewReader(b))
	decoder.UseNumber()
	decoder.Decode(&m2)
	fmt.Printf("value:%v\n", m2["count"]) // 1
	fmt.Printf("type:%T\n", m2["count"])  // json.Number
	// 將m2["count"]轉(zhuǎn)為json.Number之后調(diào)用Int64()方法獲得int64類型的值
	count, _ := m2["count"].(json.Number).Int64()
	fmt.Printf("type:%T\n", int(count)) // int
}

json.Number的源碼定義如下:

// A Number represents a JSON number literal.
type Number string
// String returns the literal text of the number.
func (n Number) String() string { return string(n) }
// Float64 returns the number as a float64.
func (n Number) Float64() (float64, error) {
	return strconv.ParseFloat(string(n), 64)
}
// Int64 returns the number as an int64.
func (n Number) Int64() (int64, error) {
	return strconv.ParseInt(string(n), 10, 64)
}

我們在處理number類型的json字段時需要先得到json.Number類型,然后根據(jù)該字段的實際類型調(diào)用Float64()Int64()

自定義解析時間字段

Go語言內(nèi)置的 json 包使用 RFC3339 標(biāo)準(zhǔn)中定義的時間格式,對我們序列化時間字段的時候有很多限制。

type Post struct {
	CreateTime time.Time `json:"create_time"`
}
func timeFieldDemo() {
	p1 := Post{CreateTime: time.Now()}
	b, _ := json.Marshal(p1) //這里會輸出RFC3339格式的時間
	fmt.Printf("str:%s\n", b)
	jsonStr := `{"create_time":"2020-04-05 12:25:42"}`
	var p2 Post
    //  反序列化時會報錯
	if err := json.Unmarshal([]byte(jsonStr), &p2); err != nil {
		fmt.Printf("json.Unmarshal failed, err:%v\n", err)
		return
	}
	fmt.Printf("p2:%#v\n", p2)
}

上面的代碼輸出結(jié)果如下:

str:{"create_time":"2023-06-01T09:28:06.799214+08:00"}
json.Unmarshal failed, err:parsing time ""2023-06-01 09:28:06"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 12:25:42"" as "T"

也就是內(nèi)置的json包不識別我們常用的字符串時間格式,如2023-06-01 12:25:42。 不過我們通過實現(xiàn) json.Marshaler/json.Unmarshaler 接口來實現(xiàn)自定義的事件格式解析。 如下,CustomTime類型實現(xiàn)了json的接口。

type CustomTime struct {
	time.Time
}
const ctLayout = "2006-01-02 15:04:05"
var nilTime = (time.Time{}).UnixNano()
// 實現(xiàn)了json.Unmarshaler接口中的方法
func (ct *CustomTime) UnmarshalJSON(b []byte) (err error) {
	s := strings.Trim(string(b), "\"")
	if s == "null" {
		ct.Time = time.Time{}
		return
	}
	ct.Time, err = time.Parse(ctLayout, s)
	return
}
// 實現(xiàn)了json.Marshaler接口中的方法
func (ct *CustomTime) MarshalJSON() ([]byte, error) {
	if ct.Time.UnixNano() == nilTime {
		return []byte("null"), nil
	}
	return []byte(fmt.Sprintf("\"%s\"", ct.Time.Format(ctLayout))), nil
}
func (ct *CustomTime) IsSet() bool {
	return ct.UnixNano() != nilTime
}
type Post struct {
	CreateTime CustomTime `json:"create_time"`
}
func timeFieldDemo() {
	p1 := Post{CreateTime: CustomTime{time.Now()}}
	b, err := json.Marshal(p1)
	if err != nil {
		fmt.Printf("json.Marshal p1 failed, err:%v\n", err)
		return
	}
	fmt.Printf("str:%s\n", b)
	jsonStr := `{"create_time":"2020-04-05 12:25:42"}`
	var p2 Post
	if err := json.Unmarshal([]byte(jsonStr), &p2); err != nil {
		fmt.Printf("json.Unmarshal failed, err:%v\n", err)
		return
	}
	fmt.Printf("p2:%#v\n", p2)
}

自定義MarshalJSON和UnmarshalJSON方法

上面那種自定義類型的方法稍顯啰嗦了一點,下面來看一種相對便捷的方法。 首先你需要知道的是,如果你能夠為某個類型實現(xiàn)了MarshalJSON()([]byte, error)UnmarshalJSON(b []byte) error方法,那么這個類型在序列化(MarshalJSON)/反序列化(UnmarshalJSON)時就會使用你定制的相應(yīng)方法。

type Order struct {
	ID          int       `json:"id"`
	Title       string    `json:"title"`
	CreatedTime time.Time `json:"created_time"`
}
const layout = "2006-01-02 15:04:05"
// MarshalJSON 為Order類型實現(xiàn)自定義的MarshalJSON方法
func (o *Order) MarshalJSON() ([]byte, error) {
	type TempOrder Order // 定義與Order字段一致的新類型
	return json.Marshal(struct {
		CreatedTime string `json:"created_time"`
		*TempOrder         // 避免直接嵌套Order進(jìn)入死循環(huán)
	}{
		CreatedTime: o.CreatedTime.Format(layout),
		TempOrder:   (*TempOrder)(o),
	})
}
// UnmarshalJSON 為Order類型實現(xiàn)自定義的UnmarshalJSON方法
func (o *Order) UnmarshalJSON(data []byte) error {
	type TempOrder Order // 定義與Order字段一致的新類型
	ot := struct {
		CreatedTime string `json:"created_time"`
		*TempOrder         // 避免直接嵌套Order進(jìn)入死循環(huán)
	}{
		TempOrder: (*TempOrder)(o),
	}
	if err := json.Unmarshal(data, &ot); err != nil {
		return err
	}
	var err error
	o.CreatedTime, err = time.Parse(layout, ot.CreatedTime)
	if err != nil {
		return err
	}
	return nil
}
// 自定義序列化方法
func customMethodDemo() {
	o1 := Order{
		ID:          123456,
		Title:       "《七米的Go學(xué)習(xí)筆記》",
		CreatedTime: time.Now(),
	}
	// 通過自定義的MarshalJSON方法實現(xiàn)struct -> json string
	b, _ := json.Marshal(&o1)
	fmt.Printf("str:%s\n", b)
	// 通過自定義的UnmarshalJSON方法實現(xiàn)json string -> struct
	jsonStr := `{"created_time":"2020-04-05 10:18:20","id":123456,"title":"《七米的Go學(xué)習(xí)筆記》"}`
	var o2 Order
	if err := json.Unmarshal([]byte(jsonStr), &o2); err != nil {
		fmt.Printf("json.Unmarshal failed, err:%v\n", err)
		return
	}
	fmt.Printf("o2:%#v\n", o2)
}

輸出結(jié)果:

str:{"created_time":"2020-04-05 10:32:20","id":123456,"title":"《七米的Go學(xué)習(xí)筆記》"}
o2:main.Order{ID:123456, Title:"《七米的Go學(xué)習(xí)筆記》", CreatedTime:time.Time{wall:0x0, ext:63721678700, loc:(*time.Location)(nil)}}

使用匿名結(jié)構(gòu)體添加字段

使用內(nèi)嵌結(jié)構(gòu)體能夠擴(kuò)展結(jié)構(gòu)體的字段,但有時候我們沒有必要單獨定義新的結(jié)構(gòu)體,可以使用匿名結(jié)構(gòu)體簡化操作

type UserInfo struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}
func anonymousStructDemo() {
	u1 := UserInfo{
		ID:   123456,
		Name: "Go學(xué)堂",
	}
	// 使用匿名結(jié)構(gòu)體內(nèi)嵌User并添加額外字段Token
	b, err := json.Marshal(struct {
		*UserInfo
		Token string `json:"token"`
	}{
		&u1,
		"91je3a4s72d1da96h",
	})
	if err != nil {
		fmt.Printf("json.Marsha failed, err:%v\n", err)
		return
	}
	fmt.Printf("str:%s\n", b)
	// str:{"id":123456,"name":"Go學(xué)堂","token":"91je3a4s72d1da96h"}
}

使用匿名結(jié)構(gòu)體組合多個結(jié)構(gòu)體

同理,也可以使用匿名結(jié)構(gòu)體來組合多個結(jié)構(gòu)體來序列化與反序列化數(shù)據(jù):

type Comment struct {
	Content string
}
type Image struct {
	Title string `json:"title"`
	URL   string `json:"url"`
}
func anonymousStructDemo2() {
	c1 := Comment{
		Content: "來學(xué)編程呀",
	}
	i1 := Image{
		Title: "Go學(xué)堂",
		URL:   "https://goxuetang.github.io",
	}
	// struct -> json string
	b, _ := json.Marshal(struct {
		*Comment
		*Image
	}{&c1, &i1})
	fmt.Printf("str:%s\n", b)
	// json string -> struct
	jsonStr := `{"Content":"來學(xué)編程呀","title":"Go學(xué)堂","url":"https://goxuetang.github.io"}`
	var (
		c2 Comment
		i2 Image
	)
	if err := json.Unmarshal([]byte(jsonStr), &struct {
		*Comment
		*Image
	}{&c2, &i2}); err != nil {
		fmt.Printf("json.Unmarshal failed, err:%v\n", err)
		return
	}
	fmt.Printf("c2:%#v i2:%#v\n", c2, i2)
}

輸出:

str:{"Content":"來學(xué)編程呀","title":"Go學(xué)堂","url":"https://goxuetang.github.io"}
c2:main.Comment{Content:"來學(xué)編程呀"} i2:main.Image{Title:"Go學(xué)堂", URL:"https://goxuetang.github.io"}

處理不確定層級的json

如果json串沒有固定的格式導(dǎo)致不好定義與其相對應(yīng)的結(jié)構(gòu)體時,我們可以使用json.RawMessage原始字節(jié)數(shù)據(jù)保存下來。

type sendMsg struct {
	User string `json:"user"`
	Msg  string `json:"msg"`
}
func rawMessageDemo() {
	jsonStr := `{"sendMsg":{"user":"Go學(xué)堂","msg":"來學(xué)編程呀"},"say":"Hello"}`
	// 定義一個map,value類型為json.RawMessage,方便后續(xù)更靈活地處理
	var data map[string]json.RawMessage
	if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
		fmt.Printf("json.Unmarshal jsonStr failed, err:%v\n", err)
		return
	}
	var msg sendMsg
	if err := json.Unmarshal(data["sendMsg"], &msg); err != nil {
		fmt.Printf("json.Unmarshal failed, err:%v\n", err)
		return
	}
	fmt.Printf("msg:%#v\n", msg)
	// msg:main.sendMsg{User:"Go學(xué)堂", Msg:"來學(xué)編程呀"}
}

總結(jié)

本文總結(jié)了Go語言在結(jié)構(gòu)體和json串之間相互之間進(jìn)行轉(zhuǎn)換時的一些技巧。同時,這些技巧也是研發(fā)者在實際項目中需要注意的地方,希望本文對你有所幫助。

以上就是超詳細(xì)Go語言中JSON處理技巧分享的詳細(xì)內(nèi)容,更多關(guān)于Go JSON處理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • golang中使用匿名結(jié)構(gòu)體的方法

    golang中使用匿名結(jié)構(gòu)體的方法

    這篇文章主要介紹了golang中使用匿名結(jié)構(gòu)體,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • golang實現(xiàn)并發(fā)控制的方法和技巧

    golang實現(xiàn)并發(fā)控制的方法和技巧

    golang 是一門支持并發(fā)的編程語言,它提供了 goroutine 和 channel 等強(qiáng)大的特性,讓我們可以輕松地創(chuàng)建和管理多個執(zhí)行單元,實現(xiàn)高效的任務(wù)處理,在本文中,我們將介紹一些 golang 的并發(fā)控制的方法和技巧,希望對你有所幫助
    2024-03-03
  • 并發(fā)安全本地化存儲go-cache讀寫鎖實現(xiàn)多協(xié)程并發(fā)訪問

    并發(fā)安全本地化存儲go-cache讀寫鎖實現(xiàn)多協(xié)程并發(fā)訪問

    這篇文章主要介紹了并發(fā)安全本地化存儲go-cache讀寫鎖實現(xiàn)多協(xié)程并發(fā)訪問,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • golang實現(xiàn)微信支付v3版本的方法

    golang實現(xiàn)微信支付v3版本的方法

    這篇文章主要介紹了golang實現(xiàn)微信支付v3版本的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Golang中文字符串截取函數(shù)實現(xiàn)原理

    Golang中文字符串截取函數(shù)實現(xiàn)原理

    在golang中可以通過切片截取一個數(shù)組或字符串,但是當(dāng)截取的字符串是中文時,可能會出現(xiàn)問題,下面我們來自定義個函數(shù)解決Golang中文字符串截取問題
    2018-03-03
  • golang 在windows中設(shè)置環(huán)境變量的操作

    golang 在windows中設(shè)置環(huán)境變量的操作

    這篇文章主要介紹了golang 在windows中設(shè)置環(huán)境變量的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • go語言中proto文件的使用

    go語言中proto文件的使用

    在Go語言編程中,.proto文件用于定義Protocol?Buffers數(shù)據(jù)結(jié)構(gòu)和服務(wù),是實現(xiàn)跨語言通信和高效序列化的關(guān)鍵,具有一定的參考價值,感興趣的可以了解一下
    2024-10-10
  • 使用GO實現(xiàn)Paxos共識算法的方法

    使用GO實現(xiàn)Paxos共識算法的方法

    這篇文章主要介紹了使用GO實現(xiàn)Paxos共識算法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • 用gomock進(jìn)行mock測試的方法示例

    用gomock進(jìn)行mock測試的方法示例

    go-mock是專門為go語言開發(fā)的mock庫,該庫使用方式簡單,支持自動生成代碼,這篇文章主要介紹了用gomock進(jìn)行mock測試的方法示例,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Golang文件讀寫操作詳情

    Golang文件讀寫操作詳情

    這篇文章主要介紹了Golang文件讀寫操作詳情,文件是數(shù)據(jù)源(保存數(shù)據(jù)的地方)的一種,文件最主要的作用就是保存數(shù)據(jù),文件在程序中是以流的形式來操作的,更多詳細(xì)內(nèi)容需要的朋友可以參考一下
    2022-07-07

最新評論