struct概述
結(jié)構(gòu)體是go語(yǔ)言最重要的數(shù)據(jù)結(jié)構(gòu)之一,go和其它編程語(yǔ)言不一樣,它沒有類的概念,類比過來struct就相當(dāng)于其它語(yǔ)言中的類,因此十分重要。
結(jié)構(gòu)體這部分涉及到的知識(shí)點(diǎn)頁(yè)比較多,此文偏長(zhǎng),請(qǐng)耐心閱讀。
1. 認(rèn)識(shí)結(jié)構(gòu)體
直接說語(yǔ)法往往非??菰铮谡介_始前,我們先來看一段簡(jiǎn)單的結(jié)構(gòu)體代碼,建立整體感知,后續(xù)我們?cè)僖灰患?xì)說其中的知識(shí)點(diǎn)。
package main import "fmt" type Person struct { Name string Age int8 } func (p Person) GetName() { fmt.Printf("My name: %s ", p.Name) } func main() { p := Person{ Name: "zhangsan", Age: 18, } p.GetName() }
看到了吧,還是很簡(jiǎn)單的,跟著注釋你大概已經(jīng)看懂了如何使用。下面我們拆分成知識(shí)點(diǎn)細(xì)細(xì)分析
1.1 如何定義
它按照如下方式定義(PS: 它還可以代標(biāo)簽,為簡(jiǎn)單起見,這里暫且不討論)
type 結(jié)構(gòu)體名 struct { 字段名1 字段類型1 字段名2 字段類型2 ..... }
1.2 實(shí)例化
主要有幾種方式:
var p = new(Person) var p Person var p = Person{} p := Person{ Name: "zhangsan", Age: 18, } p := Person{"zhangsan", 18}
實(shí)際例化后我們可以通過obj.字段名的方式調(diào)出值,如上例中p.Name
1.3 方法
結(jié)構(gòu)體方法,對(duì)應(yīng)到面向?qū)ο笳Z(yǔ)言中就是實(shí)例方法.
在上例中,如下部分:
func (p Person) GetName() { fmt.Printf("My name: %s ", p.Name) }
方法和函數(shù)有什么主要區(qū)別呢?
方法它有接收者,而函數(shù)沒有
1.4 接收者
接收者既可以是值也可以是指針類型,我們看下:
package main import "fmt" type Person struct { Name string Age int8 } func (p Person) GetName() { fmt.Printf("My name: %s ", p.Name) } func (p *Person) GetAge() { fmt.Printf("My age: %d ", p.Age) } func main() { p1 := Person{Name: "張三", Age: 18} p2 := &Person{Name: "李四", Age: 16} p1.GetName() p1.GetAge() fmt.Println("---------分割線-------") p2.GetName() p2.GetAge() }
我們可以發(fā)現(xiàn),無(wú)論接收者是值類型還是指針類型,它們?cè)谡{(diào)用上卻不會(huì)有任何區(qū)別,這是因?yàn)間o編譯器會(huì)悄悄自動(dòng)幫我轉(zhuǎn)換, nice!
1.5 指針接收者or值接收者
那么什么時(shí)候使用值接收者啥時(shí)候用指針接收者呢?
在go中一般約定,同一個(gè)struct接收者類型保持一致(要么全是指針接收者,要么全是值接收者)
值接收者:結(jié)構(gòu)體相對(duì)較?。截惓杀静桓撸恍枰淖兘Y(jié)構(gòu)體內(nèi)部值場(chǎng)景
指針接收者:結(jié)構(gòu)體比較大(拷貝成本高),需要改變結(jié)構(gòu)體內(nèi)部值場(chǎng)景
2. 匿名字段及嵌套
匿名字段可以說是結(jié)構(gòu)體最有用的功能,使用的地方比比皆是,下面我們來看下
2.1 匿名字段
所謂匿名字段指的是在結(jié)構(gòu)體中字段名可以不用顯示寫出來,比如:
package main import "fmt" type Data struct { uint8 } func main() { d := Data{8} fmt.Println(d.uint8) }
關(guān)鍵點(diǎn)在于字段名 == 類型名
2.2 結(jié)構(gòu)體嵌套
在開始之前我們來看下兩個(gè)結(jié)構(gòu)體
type Person struct { Name string Age int8 } type Student struct { ID int Name string Age int8 Score float32 }
我們會(huì)發(fā)現(xiàn)學(xué)生結(jié)構(gòu)體和人結(jié)構(gòu)體相比只多了兩個(gè)字段(ID和Score)分別定義有點(diǎn)浪費(fèi)?另外人和學(xué)生有許多相似的地方,某些時(shí)候Person結(jié)構(gòu)體中的方法,Student同樣也需要,如果分別寫兩份相同的方法,也很浪費(fèi)?
好啦!在go中可以通過嵌套解決,直接看代碼
package main import "fmt" type Person struct { Name string Age int8 } func (p Person) GetName() { fmt.Printf("My name: %s ", p.Name) } type Student struct { ID int Score float32 Person } func (s Student) GetScore() { fmt.Printf("My score: %v ", s.Score) } func main() { p := Student{ ID: 1, Score: 98, Person: Person{ Name: "zhangsan", Age: 18, }, } fmt.Printf("My age: %d ", p.Age) fmt.Printf("My age p.Person.age: %d ", p.Person.Age) p.GetScore() p.GetName() p.Person.GetName() }
上面的注釋已經(jīng)非常詳細(xì),這里總結(jié)下規(guī)律:
匿名結(jié)構(gòu)體嵌套,會(huì)有如下效果:
匿名結(jié)構(gòu)體中字段,當(dāng)前結(jié)構(gòu)體可以直接調(diào)用
匿名結(jié)構(gòu)體方法,當(dāng)前結(jié)構(gòu)體可以直接調(diào)用
本質(zhì)是:go在字段查找時(shí),現(xiàn)在本結(jié)構(gòu)體中找,如果找不到則到匿名結(jié)構(gòu)體中查找;方法同理
2.3 匿名結(jié)構(gòu)體嵌套經(jīng)典使用
數(shù)據(jù)庫(kù)表設(shè)計(jì)中: 我們可以把常用的字段抽出來成一個(gè)結(jié)構(gòu)體,其它結(jié)構(gòu)體只需要引入就可以擴(kuò)展其中字段以及方法,比如:
package main import ( "fmt" "time" ) type BaseTable struct { ID int CreatedAt time.Time UpdatedAt time.Time } type User struct { Name string BaseTable }
3. 方法值和方法表達(dá)式
方法值和方法表達(dá)式類似于函數(shù)表達(dá)式,我們可以將函數(shù)表達(dá)式當(dāng)作變量傳遞,方法值和方法表達(dá)式也是一樣,文字上不太容易明白,直接看代碼
package main import ( "fmt" ) type Person struct { Name string Age int8 } func (p Person) GetName() { fmt.Printf("My name: %s ", p.Name) } func main() { p := Person{Name: "zhangsan", Age: 18} getName := p.GetName getName() fmt.Println("--------分割線-------") pGetName := Person.GetName pGetName(p) }
它可以做為變量取出,因此可以實(shí)現(xiàn)復(fù)雜精巧場(chǎng)景下的使用,舉例這里不做舉例,方法值和方法表達(dá)式的區(qū)別在于:
方法表達(dá)式需要把接收者做為參數(shù)傳入
審核編輯:黃飛
-
指針
+關(guān)注
關(guān)注
1文章
481瀏覽量
70612 -
編譯器
+關(guān)注
關(guān)注
1文章
1642瀏覽量
49311 -
數(shù)據(jù)結(jié)構(gòu)
+關(guān)注
關(guān)注
3文章
573瀏覽量
40236 -
面向?qū)ο?/span>
+關(guān)注
關(guān)注
0文章
64瀏覽量
10004 -
Struct
+關(guān)注
關(guān)注
0文章
31瀏覽量
10902
原文標(biāo)題:golang結(jié)構(gòu)體看這篇就夠啦
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論