日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Go 分布式学习利器(9)-- Go语言 结构体的行为定义和实现

發(fā)布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go 分布式学习利器(9)-- Go语言 结构体的行为定义和实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 1. Go語言的結(jié)構(gòu)體 -- 數(shù)據(jù)成員的封裝
    • 2. Go (函數(shù)成員)行為的定義和實現(xiàn)

1. Go語言的結(jié)構(gòu)體 – 數(shù)據(jù)成員的封裝

Go語言官方給的描述是 既是面向?qū)ο笳Z言,也不算面向?qū)ο笳Z言。
不是面向?qū)ο笳Z言 是因為 Go語言并不支持繼承操作,而且對象 這個概念在Go語言中比較弱化,并不像C++/Java中 是面向?qū)ο笳Z法的核心體現(xiàn)。

是面向?qū)ο笳Z言 是因為 Go有對象的概念,也支持基本的對象封裝(包括對數(shù)據(jù)成員和成員函數(shù)的封裝)
如下:

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 運算符返回的結(jié)果 是指針類型,即類似于&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 (函數(shù)成員)行為的定義和實現(xiàn)

定義一個Person 結(jié)構(gòu)的行為(其他語言成為成員函數(shù))可以有如下兩種方式

  • 結(jié)構(gòu)體對象的復(fù)制 定義
    func (p Person) String() string { // 行為函數(shù)中傳入結(jié)構(gòu)體對象的 值return fmt.Println("id: %s-name: %s-age: %d\n", p.id,p.name,p.age)
    }
    
  • 避免內(nèi)存拷貝,結(jié)構(gòu)體對象的指針 定義
    func (p *Person) String() string { // 行為函數(shù)中傳入結(jié)構(gòu)體對象的 指針return fmt.Println("id: %s-name: %s-age: %d\n", p.id,p.name,p.age)
    }
    

關(guān)于以上,僅僅 通過結(jié)構(gòu)體對象的指針來聲明成員函數(shù)即能夠避免一次內(nèi)存拷貝,這里我的理解是:
Go語言內(nèi)部的共享內(nèi)存機制,即像數(shù)組,map等結(jié)構(gòu) 是能夠通過指針來使用同一個內(nèi)存。同樣這里的成員函數(shù)的定義,本身創(chuàng)建好結(jié)構(gòu)的對象之后就可以使用同一個對象的內(nèi)存地址完成后續(xù)相關(guān)的定義,那么Go又原生支持指針這樣的操作,何必多此一舉再進行一次內(nèi)存的分配、拷貝、釋放來降低語言本身的執(zhí)行效率。

測試函數(shù)如下:

type Person struct {id stringname stringage int
}func (p Person) String1() string{ // 多一次內(nèi)存拷貝的成員函數(shù)的實現(xiàn)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{ // 能夠避免內(nèi)存拷貝的成員函數(shù)的實現(xiàn)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)

通過以上輸出,可以看到通過 指針方式定義的成員函數(shù)String2,則擁有相同的對象地址,不需要像String1一樣進行一次內(nèi)存拷貝。

總結(jié)

以上是生活随笔為你收集整理的Go 分布式学习利器(9)-- Go语言 结构体的行为定义和实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。