后端開(kāi)發(fā)人員跟前端對(duì)接接口的時(shí)候,或多或少都會(huì)面臨一些溝通問(wèn)題,比如說(shuō)枚舉字符的定義,比如有整形狀態(tài)字段: state
創(chuàng)新互聯(lián)公司專注于云夢(mèng)企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開(kāi)發(fā),商城網(wǎng)站定制開(kāi)發(fā)。云夢(mèng)網(wǎng)站建設(shè)公司,為云夢(mèng)等地區(qū)提供建站服務(wù)。全流程按需策劃,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
通常給前端的時(shí)候,前段要做的是將1,2,3以及對(duì)應(yīng)的中文釋義存儲(chǔ)為key/value的形式,key與value單看都無(wú)法知道對(duì)方的語(yǔ)義,
比如我只知道狀態(tài)值為“1”, 是無(wú)法將其與“成功”對(duì)應(yīng)起來(lái)的(當(dāng)然這套狀態(tài)的設(shè)計(jì)者肯定是知道的),后端通常給到前端的restful api
接口定義也是key/value的形式,這乍一看其實(shí)也沒(méi)啥毛病,只要有key/value也沒(méi)問(wèn)題,后端定義通常會(huì)是
但數(shù)字的表現(xiàn)形式終歸是不不太明確的,如果對(duì)狀態(tài)的定義換成以下形式:
基本可以理解為中英文互譯了,理解起來(lái)也會(huì)更清晰一些不是,如果這么做的話,后端給到前端的響應(yīng)字段狀態(tài)的類型就需要修改成字符器格式
后端還是要做一層字符串到整型的轉(zhuǎn)換,從目的來(lái)講,我們只是想返給前端的 state 字段是字符串而已,也就是在做json序列化的時(shí)候?qū)⒄团c字符串做一層轉(zhuǎn)換,有更優(yōu)雅的做法如下所示
只需要做兩件事,自定義類型 MyState ,實(shí)現(xiàn) MarshalJSON 方法
只要類型實(shí)現(xiàn)了 MarshalJSON 方法,在json序列化時(shí)就會(huì)調(diào)用此方法,如此一來(lái),我們就輕松實(shí)現(xiàn)了自定義json序列化,反序列化同樣如此
實(shí)現(xiàn)起來(lái)也很簡(jiǎn)單
需要注意的是, UnmarshalJSON 方法操作過(guò)程需要給 receiver 也就是 u 賦值,所以必須是指針類型,同樣的,在實(shí)現(xiàn)
MarshalJSON 方法, receiver 的類型需要與結(jié)構(gòu)體定義中的類型保持一致,否則自定義序列化會(huì)失敗
參考:
json格式可以算我們?nèi)粘W畛S玫男蛄谢袷街涣耍珿o語(yǔ)言作為一個(gè)由Google開(kāi)發(fā),號(hào)稱互聯(lián)網(wǎng)的C語(yǔ)言的語(yǔ)言,自然也對(duì)JSON格式支持很好。官方提供的Json解析包已經(jīng)非常強(qiáng)大,我們接下來(lái)講解Json的序列化與反序列化操作。另外還有一些第三方的Json解析庫(kù),也能夠高效的操作Json對(duì)象,比如simplejson,ffjson等。下面是兩個(gè)比較重要的函數(shù):
? Json Marshal:將數(shù)據(jù)編碼成json字符串
Marshal 用于將struct對(duì)象序列化到j(luò)son對(duì)象中。v是interface{}類型,任何類型都實(shí)現(xiàn)了空接口。
1:tag中的第一個(gè)參數(shù)是用來(lái)指定別名,比如Name 指定別名為 username `json:"username"`
2:如果不想指定別名但是想指定其他參數(shù)用逗號(hào)來(lái)分隔,omitempty 指定到一個(gè)field時(shí),如果在賦值時(shí)對(duì)該屬性未賦值或者對(duì)該屬性賦值為 zero value,那么將Person序列化成json時(shí)會(huì)忽略該字段
3:- 指定到一個(gè)field時(shí),無(wú)論有沒(méi)有值,將Person序列化成json時(shí)都會(huì)忽略該字段
4:string 指定到一個(gè)field時(shí),比如Person中的Count為int類型 如果沒(méi)有任何指定在序列化到j(luò)son之后也是int 比如這個(gè)樣子 “Count”:0,但是如果指定了string之后序列化之后也是string類型的,那么就是這個(gè)樣子"Count":"0"
? struct序列化為Json
? slice序列化為Json
? map 序列化為Json
? Json Unmarshal:將json字符串解碼到相應(yīng)的數(shù)據(jù)結(jié)構(gòu),Unmarshal的第一個(gè)參數(shù)是[]byte,第二個(gè)參數(shù)是接受json解析的數(shù)據(jù)結(jié)構(gòu)。
下面我們依次講解Json的操作。
1:將Json序列化進(jìn)入結(jié)構(gòu)體
2::將Json序列化到結(jié)構(gòu)體slice
3:將Json序列化進(jìn)Map
4:將Json序列化進(jìn)Slice
目錄
一、結(jié)構(gòu)體詳解
1. 結(jié)構(gòu)體定義
2. 實(shí)例化結(jié)構(gòu)體的7種方法
二、結(jié)構(gòu)體方法
1. 結(jié)構(gòu)體的方法定義
2. 結(jié)構(gòu)體內(nèi)自定義方法的引用
3. 任意類型添加方法
三、嵌套、繼承
1. 匿名結(jié)構(gòu)體
2. 結(jié)構(gòu)體中可以定義任意類型的字段
3. 結(jié)構(gòu)體嵌套結(jié)構(gòu)體
4. 結(jié)構(gòu)體嵌套匿名結(jié)構(gòu)體
5. 結(jié)構(gòu)體嵌套多個(gè)匿名結(jié)構(gòu)體
6. 結(jié)構(gòu)體繼承
四、結(jié)構(gòu)體和JSON相互轉(zhuǎn)換
1. 結(jié)構(gòu)體轉(zhuǎn)化成json
2. json轉(zhuǎn)化成結(jié)構(gòu)體
3. 結(jié)構(gòu)體標(biāo)簽 tag
4. 嵌套結(jié)構(gòu)體和json的序列化反序列化
Golang 中沒(méi)有“類”的概念,Golang 中的結(jié)構(gòu)體和其他語(yǔ)言中的類有點(diǎn)相似。和其他面向?qū)?象語(yǔ)言中的類相比,Golang 中的結(jié)構(gòu)體具有更高的擴(kuò)展性和靈活性。
Golang 中的基礎(chǔ)數(shù)據(jù)類型可以表示一些事物的基本屬性,但是當(dāng)我們想表達(dá)一個(gè)事物的全 部或部分屬性時(shí),這時(shí)候再用單一的基本數(shù)據(jù)類型就無(wú)法滿足需求了,Golang 提供了一種 自定義數(shù)據(jù)類型,可以封裝多個(gè)基本數(shù)據(jù)類型,這種數(shù)據(jù)類型叫結(jié)構(gòu)體,英文名稱 struct。 也就是我們可以通過(guò) struct 來(lái)定義自己的類型了。
使用 type 和 struct 關(guān)鍵字來(lái)定義結(jié)構(gòu)體,具體代碼格式如下:
type 類型名 struct {
字段名 字段類型
字段名 字段類型 …
}
其中:
? 類型名:表示自定義結(jié)構(gòu)體的名稱,在同一個(gè)包內(nèi)不能重復(fù)。
? 字段名:表示結(jié)構(gòu)體字段名。結(jié)構(gòu)體中的字段名必須唯一。
? 字段類型:表示結(jié)構(gòu)體字段的具體類型。
在 go 語(yǔ)言中,沒(méi)有類的概念但是可以給類型(結(jié)構(gòu)體,自定義類型)定義方法。所謂方法 就是定義了接收者的函數(shù)。接收者的概念就類似于其他語(yǔ)言中的 this 或者 self。
方法的定義格式如下:
func (接收者變量 接收者類型) 方法名(參數(shù)列表) (返回參數(shù)) {
函數(shù)體
}
注意:想改變結(jié)構(gòu)體內(nèi)的值,必須先變成指針。
在 Go 語(yǔ)言中,接收者的類型可以是任何類型,不僅僅是結(jié)構(gòu)體,任何類型都可以擁有方法。 舉個(gè)例子,我們基于內(nèi)置的 int 類型使用 type 關(guān)鍵字可以定義新的自定義類型,然后為我們 的自定義類型添加方法。
注意:匿名結(jié)構(gòu)體中不允許出現(xiàn)多個(gè)重復(fù)的類型
注意:如果結(jié)構(gòu)體里面有私有屬性也就是小寫(xiě)定義的字段,則不會(huì)被json使用