Go 分布式学习利器(9)-- Go语言 结构体的行为定义和实现
生活随笔
收集整理的這篇文章主要介紹了
Go 分布式学习利器(9)-- Go语言 结构体的行为定义和实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1. Go語言的結構體 -- 數據成員的封裝
- 2. Go (函數成員)行為的定義和實現
1. Go語言的結構體 – 數據成員的封裝
Go語言官方給的描述是 既是面向對象語言,也不算面向對象語言。
不是面向對象語言 是因為 Go語言并不支持繼承操作,而且對象 這個概念在Go語言中比較弱化,并不像C++/Java中 是面向對象語法的核心體現。
是面向對象語言 是因為 Go有對象的概念,也支持基本的對象封裝(包括對數據成員和成員函數的封裝)
如下:
type Person struct {id stringname stringage int
}
實例化對象的過程如下:
obj := Person{"0", "zhang", 20} // 方法一
obj1 := Person{id:"1",name: "wang",age: 21} // 方法二
obj2 := new(Person) // 方法三
obj2.id = "2"
obj2.name = "li"
obj2.age = 22
其中通過 new 運算符返回的結果 是指針類型,即類似于&Person{},同時Go中使用指針訪問元素的時候也是通過.運算符,而不像C/C++中的->運算符
測試代碼如下:
type Person struct {id stringname stringage int
}func TestObject(t *testing.T) {obj := Person{"0", "zhang", 20}obj1 := Person{id:"1",name: "wang",age: 21}obj2 := new(Person)obj2.id = "2"obj2.name = "li"obj2.age = 22t.Log(obj)t.Log(obj1)t.Log(obj1.id)t.Log(obj2)t.Logf("obj is %T",obj) // 值類型t.Logf("obj1 is %T",obj1) // 值類型t.Logf("obj2 is %T", obj2) // 指針類型
}
最后的輸出如下
=== RUN TestObjectTestObject: oriented_test.go:19: {0 zhang 20}TestObject: oriented_test.go:20: {1 wang 21}TestObject: oriented_test.go:21: 1TestObject: oriented_test.go:23: &{2 li 22}TestObject: oriented_test.go:24: obj is Oriented_test.Person TestObject: oriented_test.go:25: obj1 is Oriented_test.PersonTestObject: oriented_test.go:26: obj2 is *Oriented_test.Person # 通過new 初始化的對象是指針類型
--- PASS: TestObject (0.00s)
2. Go (函數成員)行為的定義和實現
定義一個Person 結構的行為(其他語言成為成員函數)可以有如下兩種方式
- 結構體對象的復制 定義
func (p Person) String() string { // 行為函數中傳入結構體對象的 值return fmt.Println("id: %s-name: %s-age: %d\n", p.id,p.name,p.age) } - 避免內存拷貝,結構體對象的指針 定義
func (p *Person) String() string { // 行為函數中傳入結構體對象的 指針return fmt.Println("id: %s-name: %s-age: %d\n", p.id,p.name,p.age) }
關于以上,僅僅 通過結構體對象的指針來聲明成員函數即能夠避免一次內存拷貝,這里我的理解是:
Go語言內部的共享內存機制,即像數組,map等結構 是能夠通過指針來使用同一個內存。同樣這里的成員函數的定義,本身創建好結構的對象之后就可以使用同一個對象的內存地址完成后續相關的定義,那么Go又原生支持指針這樣的操作,何必多此一舉再進行一次內存的分配、拷貝、釋放來降低語言本身的執行效率。
測試函數如下:
type Person struct {id stringname stringage int
}func (p Person) String1() string{ // 多一次內存拷貝的成員函數的實現fmt.Printf("String1 struct address is %x\n",unsafe.Pointer(&p.id))return fmt.Sprintf("id: %s-name: %s-age: %d\n", p.id,p.name,p.age)
}func (p *Person) String2() string{ // 能夠避免內存拷貝的成員函數的實現fmt.Printf("String2 struct address is %x\n",unsafe.Pointer(&p.id))return fmt.Sprintf("id: %s-name: %s-age: %d\n", p.id,p.name,p.age)
}func TestObjectFun(t *testing.T) {obj := Person{"0", "zhang", 20}fmt.Printf("obj struct address is %x\n",unsafe.Pointer(&obj.id)) // 打印新對象的地址t.Log(obj.String1())t.Log(obj.String2())
}
輸出如下:
=== RUN TestObjectFun
obj struct address is c000090420
String1 struct address is c000090450TestObjectFun: oriented_test.go:46: id: 0-name: zhang-age: 20String2 struct address is c000090420 TestObjectFun: oriented_test.go:47: id: 0-name: zhang-age: 20--- PASS: TestObjectFun (0.00s)
通過以上輸出,可以看到通過 指針方式定義的成員函數String2,則擁有相同的對象地址,不需要像String1一樣進行一次內存拷貝。
總結
以上是生活随笔為你收集整理的Go 分布式学习利器(9)-- Go语言 结构体的行为定义和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是死飞车
- 下一篇: 《春雪》第二句是什么