Go Struct結(jié)構(gòu)體的具體實(shí)現(xiàn)
什么是結(jié)構(gòu)體
Go語(yǔ)言中沒(méi)有“類”的概念,也不支持“類”的繼承等面向?qū)ο蟮母拍?。(繼承,多態(tài),封裝)
Go語(yǔ)言中通過(guò)結(jié)構(gòu)體的內(nèi)嵌再配合接口比面向?qū)ο缶哂懈叩臄U(kuò)展性和靈活性。
1. 基本實(shí)例化(方法1)
只有當(dāng)結(jié)構(gòu)體實(shí)例化時(shí),才會(huì)真正地分配內(nèi)存(其實(shí)也就是使用new),也就是必須實(shí)例化后才能使用結(jié)構(gòu)體的字段。
結(jié)構(gòu)體本身也是一種類型,我們可以像聲明內(nèi)置類型一樣使用 var 關(guān)鍵字聲明結(jié)構(gòu)體類型。
type person struct { name string city string age int } func main() { var p1 person p1.name = "張三" p1.city = "北京" p1.age = 18 fmt.Printf("p1=%v\n", p1) // p1={張三 北京 18} fmt.Printf("p1=%#v\n", p1) // p1=main.person{name:"張三", city:"北京", age:18} }
2. new實(shí)例化(方法2)
我們還可以通過(guò)使用 new 關(guān)鍵字對(duì)結(jié)構(gòu)體進(jìn)行實(shí)例化,得到的是結(jié)構(gòu)體的地址
從打印的結(jié)果中我們可以看出 p2 是一個(gè)結(jié)構(gòu)體指針。
注意:在 Golang 中支持對(duì)結(jié)構(gòu)體指針直接使用.來(lái)訪問(wèn)結(jié)構(gòu)體的成員。
p2.name = "張三" 其實(shí)在底層是 (*p2).name = "張三"
type person struct { name string city string age int } func main() { var p2 = new(person) p2.name = "張三" p2.age = 20 p2.city = "北京" fmt.Printf("p2=%#v \n", p2) //p2=&main.person{name:"張三", city:"北京", age:20} }
3. 鍵值對(duì)初始化(方法3 結(jié)構(gòu)體能夠使用指針就使用指針)
type person struct { name string city string age int } func main() { p4 := &person{ name: "zhangsan", city: "北京", age: 18, } // p4=&main.person{name:"zhangsan", city:"北京", age:18} fmt.Printf("p4=%#v\n", p4) }
結(jié)構(gòu)體方法和接收者
1. 結(jié)構(gòu)體說(shuō)明
在 go 語(yǔ)言中,沒(méi)有類的概念但是可以給類型(結(jié)構(gòu)體,自定義類型)定義方法。所謂方法就是定義了接收者的函數(shù)。
Go語(yǔ)言中的方法(Method)是一種作用于特定類型變量的函數(shù)。這種特定類型變量叫做接收者(Receiver)。接收者的概念就類似于其他語(yǔ)言中的this或者 self。
方法的定義格式如下:
func (接收者變量 接收者類型) 方法名(參數(shù)列表) (返回值) { 函數(shù)體 }
2. 結(jié)構(gòu)體方法和接收者
給結(jié)構(gòu)體 Person 定義一個(gè)方法打印 Person 的信息
type Person struct { name string age int8 } func (p Person) printInfo() { fmt.Printf("姓名:%v 年齡:%v", p.name, p.age) // 姓名:小王子 年齡:25 } func main() { p1 := Person{ name: "小王子", age: 25, } p1.printInfo() // 姓名:小王子 年齡:25 }
3. 值類型和指針類型接收者
實(shí)例1:給結(jié)構(gòu)體 Person 定義一個(gè)方法打印 Person 的信息
值類型的接收者
- 當(dāng)方法作用于值類型接收者時(shí),Go 語(yǔ)言會(huì)在代碼運(yùn)行時(shí)將接收者的值復(fù)制一份。
- 在值類型接收者的方法中可以獲取接收者的成員值,但 修改操作只是針對(duì)副本 ,無(wú)法修改接收者變量本身。
指針類型的接收者
- 指針類型的接收者由一個(gè)結(jié)構(gòu)體的指針組成
- 由于指針的特性,調(diào)用方法時(shí)修改接收者指針的任意成員變量,在方法結(jié)束后,修改都是有效的。
- 這種方式就十分接近于其他語(yǔ)言中面向?qū)ο笾械?this 或者 self
方法大部分時(shí)候是自己處理自己的數(shù)據(jù),總結(jié)如下:
encoding-json包
1. struct與json
比如我們 Golang 要給 App 或者小程序提供 Api 接口數(shù)據(jù),這個(gè)時(shí)候就需要涉及到結(jié)構(gòu)體和Json 之間的相互轉(zhuǎn)換。
- GolangJSON 序列化是指把結(jié)構(gòu)體數(shù)據(jù)轉(zhuǎn)化成 JSON 格式的字符串
- Golang JSON 的反序列化是指把 JSON 數(shù)據(jù)轉(zhuǎn)化成 Golang 中的結(jié)構(gòu)體對(duì)象
- Golang 中 的 序 列 化 和 反 序 列 化 主 要 通 過(guò) "encoding/json" 包 中 的 json.Marshal() 和json.Unmarshal()方法實(shí)現(xiàn)
struct轉(zhuǎn)Json字符串
type Student struct { ID int Gender string name string //私有屬性不能被 json 包訪問(wèn) Sno string } func main() { var s1 = Student{ ID: 1, Gender: "男", name: "李四", Sno: "s0001", } fmt.Printf("%#v\n", s1) // main.Student{ID:1, Gender:"男", name:"李 四",Sno:"s0001"} var s, _ = json.Marshal(s1) jsonStr := string(s) fmt.Println(jsonStr) // {"ID":1,"Gender":"男","Sno":"s0001"} }
Json字符串轉(zhuǎn)struct
type Student struct { ID int Gender string Name string Sno string } func main() { var jsonStr = `{"ID":1,"Gender":"男","Name":"李四","Sno":"s0001"}` var student Student //定義一個(gè) Monster 實(shí)例 err := json.Unmarshal([]byte(jsonStr), &student) if err != nil { fmt.Printf("unmarshal err=%v\n", err) } // 反序列化后 student=main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"} student.Name="張三" fmt.Printf("反序列化后 student=%#v student.Name=%v \n", student, student.Name) }
2. struct tag
1)Tag標(biāo)簽說(shuō)明
- Tag 是結(jié)構(gòu)體的元信息,可以在運(yùn)行的時(shí)候通過(guò)反射的機(jī)制讀取出來(lái)。
- Tag 在結(jié)構(gòu)體字段的后方定義,由一對(duì)反引號(hào)包裹起來(lái)
具體的格式如下:
key1:"value1" key2:"value2"
- 結(jié)構(gòu)體 tag 由一個(gè)或多個(gè)鍵值對(duì)組成。鍵與值使用冒號(hào)分隔,值用雙引號(hào)括起來(lái)。
- 同一個(gè)結(jié)構(gòu)體字段可以設(shè)置多個(gè)鍵值對(duì) tag,不同的鍵值對(duì)之間使用空格分隔。
注意事項(xiàng):
為結(jié)構(gòu)體編寫 Tag 時(shí),必須嚴(yán)格遵守鍵值對(duì)的規(guī)則。
結(jié)構(gòu)體標(biāo)簽的解析代碼的容錯(cuò)能力很差,一旦格式寫錯(cuò),編譯和運(yùn)行時(shí)都不會(huì)提示任何錯(cuò)誤,通過(guò)反射也無(wú)法正確取值。例如不要在 key 和 value 之間添加空格。
Tag結(jié)構(gòu)體轉(zhuǎn)化Json字符串
type Student struct { ID int `json:"id"` //通過(guò)指定 tag 實(shí)現(xiàn) json 序列化該字段時(shí)的 key(表示在做json操作的時(shí)候,用json指定的字段名) Gender string `json:"gender"` Name string Sno string } func main() { var s1 = Student{ ID: 1, Gender: "男", Name: "李四", Sno: "s0001", } // main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"} fmt.Printf("%#v\n", s1) var s, _ = json.Marshal(s1) jsonStr := string(s) fmt.Println(jsonStr) // {"id":1,"gender":"男","Name":"李四","Sno":"s0001"} }
Json字符串轉(zhuǎn)成Tag結(jié)構(gòu)體
type Student struct { ID int `json:"id"` //通過(guò)指定 tag 實(shí)現(xiàn) json 序列化該字段時(shí)的 key Gender string `json:"gender"` Name string Sno string } func main() { var s2 Student var str = `{"id":1,"gender":"男","Name":"李四","Sno":"s0001"}` err := json.Unmarshal([]byte(str), &s2) if err != nil { fmt.Println(err) } // main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"} fmt.Printf("%#v", s2) }
以上就是Go Struct結(jié)構(gòu)體的具體實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Go Struct結(jié)構(gòu)體的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
GoLang使goroutine停止的五種方法實(shí)例
goroutine是Go并行設(shè)計(jì)的核心,下面這篇文章主要給大家介紹了關(guān)于GoLang使goroutine停止的五種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07詳解Golang中interface{}的注意事項(xiàng)
學(xué)習(xí)?golang?,對(duì)于?interface{}?接口類型,我們一定繞不過(guò),這篇文章咱們就來(lái)一起來(lái)看看?使用?interface{}?的時(shí)候,都有哪些注意事項(xiàng)吧2023-03-03Go語(yǔ)言中Struct與繼承與匿名字段和內(nèi)嵌結(jié)構(gòu)體全面詳解
這篇文章主要介紹了Go語(yǔ)言中Struct與繼承與匿名字段和內(nèi)嵌結(jié)構(gòu)體,Go語(yǔ)言中通過(guò)結(jié)構(gòu)體的內(nèi)嵌再配合接口比面向?qū)ο缶哂懈叩臄U(kuò)展性和靈活性,感興趣的可以了解一下2023-04-04Go語(yǔ)言并發(fā)編程之互斥鎖Mutex和讀寫鎖RWMutex
Go 語(yǔ)言中提供了很多同步工具,本文將介紹互斥鎖Mutex和讀寫鎖RWMutex的使用方法,想要具體了解的小伙伴,請(qǐng)參考下面文章詳細(xì)內(nèi)容,希望對(duì)你有所幫助2021-10-10Go?channel實(shí)現(xiàn)批量讀取數(shù)據(jù)
Go中的?channel?其實(shí)并沒(méi)有提供批量讀取數(shù)據(jù)的方法,需要我們自己實(shí)現(xiàn)一個(gè),使用本文就來(lái)為大家大家介紹一下如何通過(guò)Go?channel實(shí)現(xiàn)批量讀取數(shù)據(jù)吧2023-12-12淺析go中的map數(shù)據(jù)結(jié)構(gòu)字典
golang中的map是一種數(shù)據(jù)類型,將鍵與值綁定到一起,底層是用哈希表實(shí)現(xiàn)的,可以快速的通過(guò)鍵找到對(duì)應(yīng)的值。這篇文章主要介紹了go中的數(shù)據(jù)結(jié)構(gòu)字典-map,需要的朋友可以參考下2019-11-11Golang中g(shù)orm無(wú)法將字段更新為空值
本文主要介紹了Golang中g(shù)orm無(wú)法將字段更新為空值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05