Go 語言基礎之結構體(冬日篇)

前言

Hey,大家好呀,我是碼農,星期八,這是最後一次了,同樣也是 Go 面向對象的最後一次了。堅持住,一起看看看吧。

結構體繼承

說起繼承,學過 Java,Python 的肯定都不陌生,但是 Go 中,可沒有這個東西吶。

那咋辦呢???,還是得用結構體來實現。

假裝我們都是男孩,喜歡車,那我們就拿車來舉例子吧。

車結構體

//車
type Car struct {
    Brand  string //車品牌
    CarNum string //車牌號
    Tyre   int    //輪胎個數
}
//給車綁定一個方法,說明車的基本信息
func (this *Car) carInfo() {
    fmt.Printf("品牌:%s,車牌號:%s,輪胎個數:%d\n", this.Brand, this.CarNum, this.Tyre)
}

寶馬車

//寶馬車
type BMWCar struct {
    //*Car和Car基本沒有區別,一個存的是整個結構體,一個存的是結構體地址,用法大同小異
    *Car //這就表示繼承了Car這個結構體
}

比亞迪車

//比亞迪車
type BYDCar struct {
    *Car
}

可能看到這,你會有種熟悉得感覺,這不就是上節課所將的結構體嵌套嗎???

這跟繼承有毛關係?

其實在 Go 中,結構體既可以用來存儲數據,也可以用來模仿對象的各種操作。

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()
}

執行結果

這就是一個最簡單的,面向對象,跟其他語言一樣,繼承會將所有的屬性和方法都繼承過來。

序列化

到此爲止呢,結構體基本可以告一段落了,基本算是入門了,當然,並沒有結束,但是我想大家都累了,換個方向繼續玩。

這個東西叫做序列化,什麼意思呢,就是像咱們的切片了,map 了,結構體了等,這些都是 Go 的類型。

如果要和其他語言交流,人家可沒有這些玩意唉,那怎麼辦呢???

衆多大佬就形成了一個規範,json數據格式,json數據必須是字符串類型

最外面是'號,鍵 / 值對組合中的鍵名寫在前面並用雙引號""包裹。

就像這樣。

'{"Gender":"男","Name":"張三"}'    //'說明這個是字符串,一般打印時不顯示

序列化我們用到的是json模塊的Marshal方法。

切片序列化

單獨的切片序列化用的很少,但是仍然還是要知道。

示例代碼

package main
import (
    "encoding/json"
    "fmt"
)
type Student struct {
    Gender string
    Name   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類型轉成字符串。

執行結果

map 序列化

字典序列化,就比較有味道了,序列化的是一個標準的json數據格式。

示例代碼

package main
import (
    "encoding/json"
    "fmt"
)
type Student struct {
    Gender string
    Name   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":"張三"}
}

執行結果

這個就有點像標準的json格式了。

結構體序列化

結構體代碼

type Student struct {
    Name   string
    Gender string
    Age    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)
}

執行結果

切片套結構體

一般情況下,這種方式數據格式是用的比較多的。

當然, 還可以切片嵌套 map,方法和此方法一樣,不做例子了。

示例代碼

package main
import (
  "encoding/json"
  "fmt"
)
type Student struct {
  Name   string
  Gender string
  Age    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.Student
  if err != nil {
    fmt.Println("序列化失敗")
  }
  var serializeStr = string(serializeByte)
  fmt.Printf("serializeStr類型:%T\n" serializeStr) //string,這是字符串類型
  fmt.Printf("serializeStr值:%v\n" serializeStr)  
}

執行結果

結構體標籤 (Tag)


Tag可以理解爲結構體的說明,由一對反引號包裹起來。

但是一般情況下,Tag 在序列化是用的比較多。

結構體代碼

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.Student
  if err != nil {
    fmt.Println("序列化失敗")
  }
  var serializeStr = string(serializeByte)
  fmt.Printf("serializeStr類型:%T\n", serializeStr) //string,這是字符串類型
  fmt.Printf("serializeStr值:%v\n", serializeStr)  
}

執行結果

可以發現 key 成小寫的了,這就說明一個問題。

在序列化時,如果結構體json這個 Tag,序列化時就會以jsonTag 爲準,如果沒有jsonTag,則以結構體字段爲準

總結

上述我們學習了 Go 基礎之結構體的結構體繼承序列化結構體標籤。學完 Go 的結構體,可能你也知道了在 Go 中是如何模仿面向對象了。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ttl54woxYxKy0-wZSShFDg