真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Golang中如何使用JSON時區(qū)分空字段和未設(shè)置字段-創(chuàng)新互聯(lián)

小編給大家分享一下Golang中如何使用JSON時區(qū)分空字段和未設(shè)置字段,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

成都創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、密云網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5建站、購物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為密云等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

幾周前, 我在使用 Golang 微服務(wù), 需要添加使用 JSON 數(shù)據(jù)的 CURP 操作的支持. 通常, 我會為實體創(chuàng)建一個結(jié)構(gòu)體, 該結(jié)構(gòu)體中定義了所有字段以及 'omitempty' 屬性, 如下所示

type Article struct {
   Id   string      `json:"id"`
   Name string      `json:"name,omitempty"`
   Desc string      `json:"desc,omitempty"`
}

問題

但是這種表示形式帶來了嚴(yán)重的問題, 尤其對于 Update 或 Edit 操作而言.

例如, 假設(shè)更新請求的 JSON 數(shù)據(jù)看起來像是這樣

{"id":"1234","name":"xyz","desc":""}

注意為空的 desc 字段. 現(xiàn)在讓我們來看看這段請求數(shù)據(jù)在 Go 中解封后是怎么樣的

func Test_JSON1(t *testing.T) {         
   jsonData:=`{"id":"1234","name":"xyz","desc":""}`
   req:=Article{}
   _=json.Unmarshal([]byte(jsonData),&req)
   fmt.Printf("%+v",req)
}Output:
=== RUN   Test_JSON1
{Id:1234 Name:xyz Desc:}

這里的描述是一個空字符串, 很明顯客戶端希望將 desc 設(shè)置為空字符串, 這是由我們的程序推斷出來的.

但是, 如果客戶端不希望更改 Desc 的現(xiàn)有值, 在這種情況下, 再次發(fā)送一個描述字符串是不正確的, 因此請求的 JSON 數(shù)據(jù)可能看起來像是這樣

{"id":"1234","name":"xyz"}

我們解封到我們的結(jié)構(gòu)體中

func Test_JSON2(t *testing.T) {         
   jsonData:=`{"id":"1234","name":"xyz"}`
   req:=Article{}
   _=json.Unmarshal([]byte(jsonData),&req)
   fmt.Printf("%+v",req)
}Output:
=== RUN   Test_JSON2
{Id:1234 Name:xyz Desc:}

額, 仍然會將 Desc 作為空字符串獲取, 那么如何區(qū)分未設(shè)置字段和空字段

簡答? 指針

解決辦法

受到一些現(xiàn)有 Golang 庫的啟發(fā), 如 go-github. 我們可以將結(jié)構(gòu)體字段更改為指針類型, 如下所示

type Article struct {
   Id    string      `json:"id"`
   Name *string      `json:"name,omitempty"`
   Desc *string      `json:"desc,omitempty"`
}

通過這樣做, 我們在字段中添加了額外的狀態(tài). 如果原始 JSON 中不存在該字段, 則結(jié)構(gòu)體字段將為空 (nil).

另一方面, 如果該字段確實存在并且為空, 則指針不為空, 并且該字段包含空值.

注意 - 我沒有將 'Id' 字段更改為指針類型, 因為它不具備空狀態(tài), id 是必需的, 類似數(shù)據(jù)庫中的 id.

我們再嘗試一下.

func Test_JSON_Empty(t *testing.T) {
   jsonData := `{"id":"1234","name":"xyz","desc":""}`
   req := Article{}
   _ = json.Unmarshal([]byte(jsonData), &req)
   fmt.Printf("%+v\n", req)
   fmt.Printf("%s\n", *req.Name)
   fmt.Printf("%s\n", *req.Desc)
}
func Test_JSON_Nil(t *testing.T) {
   jsonData := `{"id":"1234","name":"xyz"}`
   req := Article{}
   _ = json.Unmarshal([]byte(jsonData), &req)
   fmt.Printf("%+v\n", req)
   fmt.Printf("%s\n", *req.Name)
}

Output

=== RUN   Test_JSON_Empty
{Id:1234 Name:0xc000088540 Desc:0xc000088550}
Name: xyz
Desc: 
--- PASS: Test_JSON_Empty (0.00s)=== RUN   Test_JSON_Nil
{Id:1234 Name:0xc00005c590 Desc:}
Name: xyz
--- PASS: Test_JSON_Nil (0.00s)

第一種情況, 由于 desc 設(shè)置為空字符串, 因此我們在 Desc 獲得了一個非空指針并包含一個空字符串的值. 第二種情況, 該字段未設(shè)置, 我們得到了一個空字符串指針.

因此我們能夠區(qū)分兩種更新. 這種方式不僅適用于字符串, 而且適用于其他的所有數(shù)據(jù)類型, 包括整型, 嵌套結(jié)構(gòu)體, 等.

但是這種方法也存在一些問題.

空安全性: 非指針數(shù)據(jù)類型具備固有的空安全性. 在 Golang 中這意味著字符串或整型永遠(yuǎn)不能為空. 他們始終具備默認(rèn)值. 但是如果定義了指針, 則這些數(shù)據(jù)類型在未手動設(shè)置的情況下默認(rèn)為空. 因此, 嘗試在不驗證可空性的情況下訪問那些指針的數(shù)據(jù)可能會導(dǎo)致應(yīng)用程序崩潰.

# 以下代碼將崩潰, 因為 desc 為空
func Test_JSON_Nil(t *testing.T) {
   jsonData := `{"id":"1234","name":"xyz"}`
   req := Article{}
   _ = json.Unmarshal([]byte(jsonData), &req)
   fmt.Printf("%+v\n", req)
   fmt.Printf("%s\n", *req.Desc)
}

通過始終檢查空指針可以很容易的解決此問題, 但你的代碼可能會看起來會很啰嗦.

可打印性: 如在基于指針的解決方案的輸出中你可能已經(jīng)注意到的問題, 不會打印指針的值. 二十打印了指針的十六進(jìn)制值, 這在應(yīng)用程序中沒什么用. 這也可以通過重新使用 stringer 接口來克服.

func (a *Article) String() string {
   output:=fmt.Sprintf("Id: %s ",a.Id)
   if a.Name!=nil{
   output+=fmt.Sprintf("Name: '%s' ",*a.Name)
   }
   if u.Desc!=nil{
   output+=fmt.Sprintf("Desc: '%s' ",u.Desc)
   }
   return output
}

附錄:

  • 解決上述問題的另一種方法是使用具有可為空類型的三方庫, 其類型可提供檢查是否為空的方法, 而無需關(guān)心指針.
  • github.com/guregu/null
  • github.com/google/go-github

看完了這篇文章,相信你對Golang中如何使用JSON時區(qū)分空字段和未設(shè)置字段有了一定的了解,想了解更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!


分享題目:Golang中如何使用JSON時區(qū)分空字段和未設(shè)置字段-創(chuàng)新互聯(lián)
標(biāo)題URL:http://weahome.cn/article/doedhj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部