深入理解Go語言中的結(jié)構(gòu)體
概述
在上一節(jié)的內(nèi)容中,我們介紹了Go的函數(shù),包括:函數(shù)定義、函數(shù)聲明、函數(shù)調(diào)用、可變參數(shù)函數(shù)、匿名函數(shù)、遞歸函數(shù)、高階函數(shù)等。在本節(jié)中,我們將介紹Go的結(jié)構(gòu)體。在Go語言中,結(jié)構(gòu)體是一種用戶定義的數(shù)據(jù)類型,它允許你組合不同類型的字段來表示一個復雜的數(shù)據(jù)結(jié)構(gòu)。結(jié)構(gòu)體可以包含零個或多個字段,每個字段都有一個名稱和一個對應的數(shù)據(jù)類型。
定義結(jié)構(gòu)體
在Go語言中,我們使用type關(guān)鍵字來定義一個結(jié)構(gòu)體類型,并指定結(jié)構(gòu)體的字段及對應的數(shù)據(jù)類型。以下是定義結(jié)構(gòu)體的基本語法:
type StructName struct {
field1 type1
field2 type2
// ...
}其中,StructName是結(jié)構(gòu)體的名稱,field1、field2等是字段的名稱,type1、type2等是字段對應的數(shù)據(jù)類型。
在下面的示例代碼中,我們定義了一個名為Person的結(jié)構(gòu)體類型。它包含兩個字段:Name和Age,分別表示人的姓名和年齡。
type Person struct {
name string
age int
}聲明結(jié)構(gòu)體變量
定義結(jié)構(gòu)體類型后,我們就可以使用該類型聲明變量并為其分配內(nèi)存空間了。在下面的示例代碼中,我們聲明了一個名為person1的結(jié)構(gòu)體變量,并使用字面量初始化它的各個字段值。如果有字段未賦值,則使用該類型的默認值。
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
person1 := Person{name: "Mike", age: 18}
// 輸出:{Mike 18}
fmt.Println(person1)
person2 := Person{name: "Tom"}
// 輸出:{Tom 0}
fmt.Println(person2)
}初始化結(jié)構(gòu)體變量時,也可以不指定鍵值。此時,會按順序賦值給結(jié)構(gòu)體的各個字段。
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
// 不指定鍵值
person1 := Person{"Mike", 18}
// 輸出:{Mike 18}
fmt.Println(person1)
}使用結(jié)構(gòu)體
聲明結(jié)構(gòu)體變量后,我們可以使用.運算符來訪問和修改結(jié)構(gòu)體變量中的字段。
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
person1 := Person{name: "Mike", age: 18}
// 輸出:name is Mike
fmt.Println("name is", person1.name)
person1.age = 20
// 輸出:age is 20
fmt.Println("age is", person1.age)
}結(jié)構(gòu)體也可以在函數(shù)中作為參數(shù)傳遞。注意:傳入函數(shù)中的結(jié)構(gòu)體變量拷貝了一份,并不是原始變量;在函數(shù)內(nèi)部修改結(jié)構(gòu)體字段的值,并不會影響原始變量。在下面的示例代碼中,我們在AddPrice()函數(shù)中增加了書籍的價格,但main()函數(shù)中book結(jié)構(gòu)體變量的price字段仍是原來的100。
package main
import "fmt"
type Book struct {
name string
price int
}
func AddPrice(book Book) {
book.price += 20
}
func main() {
book := Book{name: "Go to Learn Go", price: 100}
// 輸出:100
fmt.Println(book.price)
AddPrice(book)
// 輸出:100
fmt.Println(book.price)
}如果我們需要AddPrice()函數(shù)對價格的修改能夠影響原始的book變量,則需要向AddPrice()函數(shù)中傳入結(jié)構(gòu)體指針。
package main
import "fmt"
type Book struct {
name string
price int
}
func AddPrice(pBook *Book) {
pBook.price += 20
}
func main() {
book := Book{name: "Go to Learn Go", price: 100}
// 輸出:100
fmt.Println(book.price)
pBook := &book
AddPrice(pBook)
// 輸出:120
fmt.Println(book.price)
}結(jié)構(gòu)體關(guān)聯(lián)函數(shù)
在Go語言中,可以通過在結(jié)構(gòu)體上定義函數(shù)來實現(xiàn)與結(jié)構(gòu)體關(guān)聯(lián)的函數(shù)。這些函數(shù)可以訪問和操作結(jié)構(gòu)體的字段,以實現(xiàn)特定的功能。要關(guān)聯(lián)函數(shù)與結(jié)構(gòu)體,首先需要定義一個函數(shù),函數(shù)的接收者類型需指定為該結(jié)構(gòu)體類型。然后,在函數(shù)內(nèi)部,可以直接訪問結(jié)構(gòu)體的字段,也可以調(diào)用其他與該結(jié)構(gòu)體相關(guān)的函數(shù)。
package main
import "fmt"
type Book struct {
name string
price int
}
// 結(jié)構(gòu)體關(guān)聯(lián)函數(shù)
func (pBook *Book) AddPrice(offset int) {
pBook.price += offset
}
func main() {
book := Book{name: "Go to Learn Go", price: 100}
// 輸出:100
fmt.Println(book.price)
pBook := &book
// 關(guān)聯(lián)后,使用結(jié)構(gòu)體變量直接調(diào)用函數(shù)
pBook.AddPrice(66)
// 輸出:166
fmt.Println(book.price)
}Go語言中的結(jié)構(gòu)體沒有其他語言中構(gòu)造器的概念,但我們可以參考下面的示例代碼來模擬構(gòu)造器。
package main
import "fmt"
type Book struct {
name string
price int
}
// 模擬的構(gòu)造器
func NewBook(name string, price int) *Book {
book := Book{name: name, price: price}
return &book
}
// 結(jié)構(gòu)體關(guān)聯(lián)函數(shù)
func (pBook *Book) AddPrice(offset int) {
pBook.price += offset
}
func main() {
pBook := NewBook("Go to Learn Go", 100)
// 輸出:100
fmt.Println(pBook.price)
pBook.AddPrice(66)
// 輸出:166
fmt.Println(pBook.price)
}new
在Go語言中,new是一個內(nèi)建函數(shù),用于分配內(nèi)存并返回指向該內(nèi)存的指針。它接受一個類型作為參數(shù),并返回一個指向該類型的新分配的零值的指針。new函數(shù)的語法如下:
new(T)
其中,T表示要分配的類型。使用new函數(shù)可以方便地分配一個新的值,并返回指向該值的指針,這個指針可以被用于進一步初始化該值或訪問其成員。
package main
import "fmt"
type Book struct {
name string
price int
}
func main() {
pBook := new(Book)
pBook.name = "Go to Learn Go"
pBook.price = 66
// 輸出:Go to Learn Go 66
fmt.Println(pBook.name, pBook.price)
}組合
Go語言并不直接支持傳統(tǒng)的基于類的繼承和派生,而是采用了組合的方式來實現(xiàn)類似的功能。組合是一種面向?qū)ο缶幊痰奶匦?,它允許在一個類型中嵌入另一個類型,從而擴展和組合已有的功能。Go語言中的組合是通過結(jié)構(gòu)體來實現(xiàn)的,可以在結(jié)構(gòu)體中嵌入其他結(jié)構(gòu)體或類型。這種方式允許我們在已有的類型上添加新的功能,而不需要通過繼承來共享狀態(tài)和行為。
在下面的示例代碼中,我們定義了一個Base結(jié)構(gòu)體和一個Derived結(jié)構(gòu)體。Derived結(jié)構(gòu)體嵌入了Base結(jié)構(gòu)體,從而可以訪問Base的函數(shù)和字段。通過在Derived結(jié)構(gòu)體上定義新的函數(shù)DerivedFunc,我們?yōu)锽ase類型添加了新的功能。在main函數(shù)中,我們創(chuàng)建了一個Derived類型的實例,并分別調(diào)用了BaseFunc和DerivedFunc函數(shù)。
package main
import "fmt"
// 定義一個基礎(chǔ)類型
type Base struct {
name string
number int
}
// 基礎(chǔ)類型關(guān)聯(lián)函數(shù)
func (b *Base) BaseFunc() {
fmt.Printf("Base func: %s, %d\n", b.name, b.number)
}
// 定義一個擴展類型,并嵌入基礎(chǔ)類型
type Derived struct {
Base
dataEx int
}
// 擴展類型關(guān)聯(lián)函數(shù)
func (d *Derived) DerivedFunc() {
fmt.Printf("Derived func: %s, %d, %d\n", d.name, d.number, d.dataEx)
}
func main() {
// 創(chuàng)建擴展類型的實例
derived := &Derived{dataEx: 100}
derived.Base = Base{name: "CSDN", number: 66}
// 調(diào)用基礎(chǔ)方法,輸出: Base func: CSDN, 66
derived.BaseFunc()
// 調(diào)用擴展方法,輸出: Derived func: CSDN, 66, 100
derived.DerivedFunc()
}到此這篇關(guān)于深入理解Go語言中的結(jié)構(gòu)體的文章就介紹到這了,更多相關(guān)Go語言 結(jié)構(gòu)體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- golang使用泛型結(jié)構(gòu)體實現(xiàn)封裝切片
- go語言中結(jié)構(gòu)體tag使用小結(jié)
- Golang?中判斷兩個結(jié)構(gòu)體相等的方法
- Go語言中結(jié)構(gòu)體的高級技巧分享
- Go中匿名結(jié)構(gòu)體的使用技巧
- 詳解Golang time包中的結(jié)構(gòu)體time.Ticker
- 詳解Golang time包中的結(jié)構(gòu)體time.Time
- 詳解Go語言中的結(jié)構(gòu)體的特性
- 一文帶你感受Go語言空結(jié)構(gòu)體的魔力
- 細說Go語言中空結(jié)構(gòu)體的奇妙用途
- 一文帶你掌握掌握 Golang結(jié)構(gòu)體與方法
相關(guān)文章
Go 語言json.Unmarshal 遇到的小問題(推薦)
這篇文章主要介紹了 Go 語言json.Unmarshal 遇到的小問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
在Mac中搭建go語言開發(fā)環(huán)境的操作步驟
go語言在開發(fā)效率和運行效率中的優(yōu)勢讓很多人青睞,所以有傾向打算轉(zhuǎn)向go語言的開發(fā)。下面介紹在Mac中g(shù)olang的開發(fā)環(huán)境配置。有需要的可以參考借鑒。2016-08-08
Go使用Gin+mysql實現(xiàn)增刪改查的詳細實例
golang本身沒有提供連接mysql的驅(qū)動,但是定義了標準接口供第三方開發(fā)驅(qū)動,下面這篇文章主要給大家介紹了關(guān)于Go使用Gin+mysql實現(xiàn)增刪改查的相關(guān)資料,需要的朋友可以參考下2022-12-12

