Go語言基礎(chǔ)之結(jié)構(gòu)體(冬日篇)
回復“ Go語言 ”即可獲贈從入門到進階共10本電子書
今
日
雞
湯
曲終收撥當心畫,四弦一聲如裂帛。前言
Hey,大家好呀,我是碼農(nóng),星期八,這是最后一次了,同樣也是Go面向?qū)ο蟮淖詈笠淮瘟恕猿肿。黄鹂纯纯窗伞?/span>
結(jié)構(gòu)體繼承
說起繼承,學過Java,Python的肯定都不陌生,但是Go中,可沒有這個東西吶。
那咋辦呢???,還是得用結(jié)構(gòu)體來實現(xiàn)。
假裝我們都是男孩,喜歡車,那我們就拿車來舉例子吧。
車結(jié)構(gòu)體
//車type Car struct {Brand string //車品牌CarNum string //車牌號Tyre int //輪胎個數(shù)}
//給車綁定一個方法,說明車的基本信息func (this *Car) carInfo() {fmt.Printf("品牌:%s,車牌號:%s,輪胎個數(shù):%d\n", this.Brand, this.CarNum, this.Tyre)}
寶馬車
//寶馬車type BMWCar struct {//*Car和Car基本沒有區(qū)別,一個存的是整個結(jié)構(gòu)體,一個存的是結(jié)構(gòu)體地址,用法大同小異*Car //這就表示繼承了Car這個結(jié)構(gòu)體}
比亞迪車
//比亞迪車type BYDCar struct {*Car}
可能看到這,你會有種熟悉得感覺,這不就是上節(jié)課所將的結(jié)構(gòu)體嵌套嗎???
這跟繼承有毛關(guān)系?
其實在Go中,結(jié)構(gòu)體既可以用來 存儲數(shù)據(jù) ,也可以 用來模仿對象 的各種操作。
main代碼
func main() {//一個寶馬對象var bmw1 = BMWCar{&Car{Brand: "寶馬x8",CarNum: "京666",Tyre: 4,}}//一個比亞迪對象var byd1 = BYDCar{&Car{Brand: "比亞迪L3",CarNum: "京111",Tyre: 4,}}//因為 BMWCar 和 BYDCar 都繼承了Car,所以都有carInfo這個方法bmw1.carInfo()byd1.carInfo()}
執(zhí)行結(jié)果

這就是一個最簡單的,面向?qū)ο螅渌Z言一樣,繼承會將所有的屬性和方法都繼承過來。
序列化
到此為止呢,結(jié)構(gòu)體基本可以告一段落了,基本算是入門了,當然,并沒有結(jié)束,但是我想大家都累了,換個方向繼續(xù)玩。
這個東西叫做序列化,什么意思呢,就是像咱們的 切片 了, map 了, 結(jié)構(gòu)體 了等,這些都是Go的類型。
如果要和其他語言交流,人家可沒有這些玩意唉,那怎么辦呢???
眾多大佬就形成了一個規(guī)范, json 數(shù)據(jù)格式, json 數(shù)據(jù)必須是 字符串類型 。
最外面是 ' 號,鍵/值對組合中的鍵名寫在前面并用雙引號 "" 包裹。
就像這樣。
'{"Gender":"男","Name":"張三"}' //'說明這個是字符串,一般打印時不顯示
序列化我們用到的是 json 模塊的 Marshal 方法。
切片序列化
單獨的切片序列化用的很少,但是仍然還是要知道。
示例代碼
package main
import ("encoding/json""fmt")
type Student struct {Gender stringName string}
func main() {var StudentList = []string{"張三", "李四"}fmt.Printf("StudentList類型:%T\n", StudentList) //[]string,這是列表類型serializeByte, err := json.Marshal(StudentList)if err != nil {fmt.Println("序列化失敗")return}var serializeStr = string(serializeByte)fmt.Printf("serializeStr類型:%T\n", serializeStr) //string,這是字符串類型fmt.Printf("serializeStr值:%v\n", serializeStr) //["張三","李四"]}
第16行代碼將切片序列化,但是返回的是 []byte 類型,第21行代碼將 []byte 類型轉(zhuǎn)成字符串。
執(zhí)行結(jié)果

map序列化
字典序列化,就比較有味道了,序列化的是一個標準的 json 數(shù)據(jù)格式。
示例代碼
package main
import ("encoding/json""fmt")
type Student struct {Gender stringName string}
func main() {var StudentInfo = map[string]string{"Name":"張三","Age":"18","Gender":"男",}fmt.Printf("StudentInfo類型:%T\n",StudentInfo)serializeByte, err := json.Marshal(StudentInfo)if err != nil {fmt.Println("序列化失敗")}var serializeStr = string(serializeByte)fmt.Printf("serializeStr類型:%T\n", serializeStr) //string,這是字符串類型fmt.Printf("serializeStr值:%v\n", serializeStr) //{"Age":"18","Gender":"男","Name":"張三"}}
執(zhí)行結(jié)果

這個就有點像標準的 json 格式了。
結(jié)構(gòu)體序列化
結(jié)構(gòu)體代碼
type Student struct {Name stringGender stringAge int}
main
func main() {var s1 = Student{Name: "張三",Gender: "男",Age: 18,}fmt.Printf("StudentInfo類型:%T\n", s1)serializeByte, err := json.Marshal(s1)if err != nil {fmt.Println("序列化失敗")}var serializeStr = string(serializeByte)fmt.Printf("serializeStr類型:%T\n", serializeStr) //string,這是字符串類型fmt.Printf("serializeStr值:%v\n", serializeStr)}
執(zhí)行結(jié)果

切片套結(jié)構(gòu)體
一般情況下,這種方式數(shù)據(jù)格式是用的比較多的。
當然, 還可以切片嵌套map,方法和此方法一樣,不做例子了。
示例代碼
package main
import ("encoding/json""fmt")
type Student struct {Name stringGender stringAge int}
func main() {var s1 = Student{Name: "張三",Gender: "男",Age: 18,}var s2 = Student{Name: "李四",Gender: "女",Age: 16,}//一個存放 Student 的列表var studentList = []Student{s1, s2}fmt.Printf("StudentInfo類型:%T\n", studentList)serializeByte, err := json.Marshal(studentList) //main.Studentif err != nil {fmt.Println("序列化失敗")}var serializeStr = string(serializeByte)fmt.Printf("serializeStr類型:%T\n", serializeStr) //string,這是字符串類型fmt.Printf("serializeStr值:%v\n", serializeStr)}
執(zhí)行結(jié)果

結(jié)構(gòu)體標簽(Tag)
Tag 可以理解為結(jié)構(gòu)體的說明,由一對 反引號 包裹起來。
但是一般情況下,Tag在序列化是用的比較多。
結(jié)構(gòu)體代碼
type Student struct {Name string `json:"name"`Gender string `json:"gender"`Age int `json:"age"`}
每個字段后面跟的,就是 Tag ,一定不要把格式搞錯啦。
main代碼
func main() {var s1 = Student{Name: "張三",Gender: "男",Age: 18,}fmt.Printf("StudentInfo類型:%T\n", s1)serializeByte, err := json.Marshal(s1) //main.Studentif err != nil {fmt.Println("序列化失敗")}var serializeStr = string(serializeByte)fmt.Printf("serializeStr類型:%T\n", serializeStr) //string,這是字符串類型fmt.Printf("serializeStr值:%v\n", serializeStr)}
執(zhí)行結(jié)果

可以發(fā)現(xiàn) key 成小寫的了,這就說明一個問題。
在序列化時,如果 結(jié)構(gòu)體 有 json 這個Tag,序列化時就會以 json Tag為準,如果沒有 json Tag,則以 結(jié)構(gòu)體字段為準 。
總結(jié)
上述我們學習了Go基礎(chǔ)之結(jié)構(gòu)體的 結(jié)構(gòu)體繼承 , 序列化 , 結(jié)構(gòu)體標簽 。學完Go的結(jié)構(gòu)體,可能你也知道了在Go中是如何模仿面向?qū)ο罅恕?/span>
一定記得多多實踐,多多敲代碼。如果在操作過程中有任何問題,記得下面討論區(qū)留言,我們看到會第一時間解決問題。
我是碼農(nóng)星期八,如果覺得還不錯,記得動手點贊一下哈。感謝你的觀看。
------------------- End -------------------
往期精彩文章推薦:
歡迎大家點贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持
想加入Go學習群請在后臺回復【 入群 】
萬水千山總是情,點個【 在看 】行不行
/今日留言主題/
