最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang通脈之方法詳情

 更新時間:2021年10月22日 14:18:10   作者:羌  
這篇文章主要介紹了Golang通脈方法,Go語言中的方法(Method)是一種作用于特定類型變量的函數(shù)。這種特定類型變量叫做接收者(Receiver)。接收者的概念就類似于,其他語言中的this或者 self,具體內(nèi)容請和小編一起來學(xué)習(xí)下面文章內(nèi)容吧

方法和接收者

Go語言中的方法(Method)是一種作用于特定類型變量的函數(shù)。這種特定類型變量叫做接收者(Receiver)。接收者的概念就類似于其他語言中的this或者 self。

Go 語言中同時有函數(shù)和方法。一個方法就是一個包含了接受者的函數(shù),接受者可以是命名類型或者結(jié)構(gòu)體類型的一個值或者是一個指針。所有給定類型的方法屬于該類型的方法集

方法只是一個函數(shù),它帶有一個特殊的接收器類型,它是在func關(guān)鍵字和方法名之間編寫的。接收器可以是struct類型或非struct類型。接收方可以在方法內(nèi)部訪問。

方法能給用戶自定義的類型添加新的行為。它和函數(shù)的區(qū)別在于方法有一個接收者,給一個函數(shù)添加一個接收者,那么它就變成了方法。接收者可以是值接收者,也可以是指針接收者。

在調(diào)用方法的時候,值類型既可以調(diào)用值接收者的方法,也可以調(diào)用指針接收者的方法;指針類型既可以調(diào)用指針接收者的方法,也可以調(diào)用值接收者的方法。

也就是說,不管方法的接收者是什么類型,該類型的值和指針都可以調(diào)用,不必嚴(yán)格符合接收者的類型。

方法的定義格式如下:

func (t Type) methodName(parameter)(return) {
  
}

其中

  • t:接收者中的參數(shù)變量名在命名時,官方建議使用接收者類型名稱首字母的小寫,而不是self、this之類的命名。
  • Type:接收者類型和參數(shù)類似,可以是指針類型和非指針類型。
  • methodName、parameter 、return :具體格式與函數(shù)定義相同。
//Person 結(jié)構(gòu)體
type Person struct {
 name string
 age  int8
}
 
//NewPerson 構(gòu)造函數(shù)
func NewPerson(name string, age int8) *Person {
 return &Person{
  name: name,
  age:  age,
 }
}
 
//Dream Person做夢的方法
func (p Person) Dream() {
 fmt.Printf("%s的夢想是學(xué)好Go語言!\n", p.name)
}
 
func main() {
 p1 := NewPerson("張三", 25)
 p1.Dream()
}


方法與函數(shù)的區(qū)別是,函數(shù)不屬于任何類型,方法屬于特定的類型。

可以定義相同的方法名:

type Rectangle struct {
 width, height float64
}
type Circle struct {
 radius float64
}
 
 
func (r Rectangle) area() float64 {
 return r.width * r.height
}
//該 method 屬于 Circle 類型對象中的方法
func (c Circle) area() float64 {
 return c.radius * c.radius * math.Pi
}
func main() {
 r1 := Rectangle{12, 2}
 r2 := Rectangle{9, 4}
 c1 := Circle{10}
 c2 := Circle{25}
 fmt.Println("Area of r1 is: ", r1.area())
 fmt.Println("Area of r2 is: ", r2.area())
 fmt.Println("Area of c1 is: ", c1.area())
 fmt.Println("Area of c2 is: ", c2.area())
}

運(yùn)行結(jié)果:

Area of r1 is:  24
Area of r2 is:  36
Area of c1 is:  314.1592653589793
Area of c2 is:  1963.4954084936207

  • 雖然method的名字一模一樣,但是如果接收者不一樣,那么method就不一樣
  • method里面可以訪問接收者的字段
  • 調(diào)用method通過.訪問,就像struct里面訪問字段一樣

指針類型的接收者

指針類型的接收者由一個結(jié)構(gòu)體的指針組成,由于指針的特性,調(diào)用方法時修改接收者指針的任意成員變量,在方法結(jié)束后,修改都是有效的。這種方式就十分接近于其他語言中面向?qū)ο笾械?code>this或者self

type Rectangle struct {
 width, height int
}
 
func (r *Rectangle) setVal() {
 r.height = 20
}
 
func main() {
 p := Rectangle{1, 2}
 s := p
 p.setVal()
 fmt.Println(p.height, s.height)
}

結(jié)果:

20 2

值類型的接收者

當(dāng)方法作用于值類型接收者時,Go語言會在代碼運(yùn)行時將接收者的值復(fù)制一份。在值類型接收者的方法中可以獲取接收者的成員值,但修改操作只是針對副本,無法修改接收者變量本身。

type Rectangle struct {
 width, height int
}
 
func (r Rectangle) setVal() {
 r.height = 20
}
 
func main() {
 p := Rectangle{1, 2}
 s := p
 p.setVal()
 fmt.Println(p.height, s.height)  // 2 2
}

什么時候應(yīng)該使用指針類型接收者

  • 需要修改接收者中的值
  • 接收者是拷貝代價(jià)比較大的大對象
  • 保證一致性,如果有某個方法使用了指針接收者,那么其他的方法也應(yīng)該使用指針接收者。

方法和函數(shù)

已經(jīng)有了函數(shù),為什么還要使用方法?

type Employee struct {  
    name     string
    salary   int
    currency string
}
 
/*
 displaySalary() method converted to function with Employee as parameter
*/
func displaySalary(e Employee) {  
    fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}
 
func main() {  
    emp1 := Employee{
        name:     "Sam Adolf",
        salary:   5000,
        currency: "$",
    }
    displaySalary(emp1)
}

在上面的程序中,displaySalary方法被轉(zhuǎn)換為一個函數(shù),而Employee struct作為參數(shù)傳遞給它。這個程序也產(chǎn)生了相同的輸出:Salary of Sam Adolf is $5000.。

為什么可以用函數(shù)來寫相同的程序呢?有以下幾個原因:

Go不是一種純粹面向?qū)ο蟮木幊陶Z言,它不支持類。因此,類型的方法是一種實(shí)現(xiàn)類似于類的行為的方法。
相同名稱的方法可以在不同的類型上定義,而具有相同名稱的函數(shù)是不允許的。

任意類型添加方法

在Go語言中,接收者的類型可以是任何類型,不僅僅是結(jié)構(gòu)體,任何類型都可以擁有方法。 舉個例子,我們基于內(nèi)置的int類型使用type關(guān)鍵字可以定義新的自定義類型,然后為我們的自定義類型添加方法。

//MyInt 將int定義為自定義MyInt類型
type MyInt int
 
//SayHello 為MyInt添加一個SayHello的方法
func (m MyInt) SayHello() {
 fmt.Println("Hello, 我是一個int。")
}
func main() {
 var m1 MyInt
 m1.SayHello() //Hello, 我是一個int。
 m1 = 100
 fmt.Printf("%#v  %T\n", m1, m1) //100  main.MyInt
}

注意事項(xiàng): 非本地類型不能定義方法,也就是說我們不能給別的包的類型定義方法。

方法繼承

方法是可以繼承的,如果匿名字段實(shí)現(xiàn)了一個方法,那么包含這個匿名字段的struct也能調(diào)用該方法

type Human struct {
 name  string
 age   int
 phone string
}
type Student struct {
 Human  //匿名字段
 school string
}
type Employee struct {
 Human   //匿名字段
 company string
}
 
func (h *Human) SayHi() {
 fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {
 mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
 sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
 mark.SayHi()
 sam.SayHi()
}

運(yùn)行結(jié)果:

Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam you can call me on 111-888-XXXX

方法重寫

type Human struct {
 name  string
 age   int
 phone string
}
type Student struct {
 Human  //匿名字段
 school string
}
type Employee struct {
 Human   //匿名字段
 company string
}
 
//Human定義method
func (h *Human) SayHi() {
 fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
 
//Employee的method重寫Human的method
func (e *Employee) SayHi() {
 fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
  e.company, e.phone) //Yes you can split into 2 lines here.
}
func main() {
 mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
 sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
 mark.SayHi()
 sam.SayHi()
}



運(yùn)行結(jié)果:

Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam, I work at Golang Inc. Call me on 111-888-XXXX

  • 方法是可以繼承和重寫的
  • 存在繼承關(guān)系時,按照就近原則,進(jìn)行調(diào)用

結(jié)構(gòu)體和方法補(bǔ)充

因?yàn)?code>slice和map這兩種數(shù)據(jù)類型都包含了指向底層數(shù)據(jù)的指針,因此在需要復(fù)制它們時要特別注意:

type Person struct {
 name   string
 age    int8
 dreams []string
}
 
func (p *Person) SetDreams(dreams []string) {
 p.dreams = dreams
}
 
func main() {
 p1 := Person{name: "張三", age: 18}
 data := []string{"吃飯", "睡覺", "打豆豆"}
 fmt.Printf("%p\n",data)  //0xc00006e360
 p1.SetDreams(data)      //傳的是 data 的內(nèi)存地址,此時p.dreams和data指向同一塊內(nèi)存空間
 fmt.Printf("%p\n",p1.dreams) //0xc00006e360
 
 // 你真的想要修改 p1.dreams 嗎?
 data[1] = "不睡覺"    //data值的修改會影響person結(jié)構(gòu)體的dream字段
 fmt.Println(p1.dreams)  // [吃飯 不睡覺 打豆豆]
}

正確的做法是在方法中使用傳入的slice的拷貝進(jìn)行結(jié)構(gòu)體賦值。

func (p *Person) SetDreams(dreams []string) {
 p.dreams = make([]string, len(dreams))
 copy(p.dreams, dreams)
}


同樣的問題也存在于返回值slicemap的情況,在實(shí)際編碼過程中一定要注意這個問題。

到此這篇關(guān)于Golang通脈方法詳情的文章就介紹到這了,更多相關(guān)Golang通脈方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang雙指針快速排序的實(shí)現(xiàn)代碼

    golang雙指針快速排序的實(shí)現(xiàn)代碼

    這篇文章主要介紹了golang雙指針快速排序的實(shí)現(xiàn)代碼,通過實(shí)例代碼補(bǔ)充介紹了Golang實(shí)現(xiàn)快速排序和歸并排序以及堆排序算法全注釋,需要的朋友可以參考下
    2024-03-03
  • Go 面向包新提案透明文件夾必要性分析

    Go 面向包新提案透明文件夾必要性分析

    這篇文章主要為大家介紹了Go 面向包新提案,透明文件夾必要性分析,看看是否合適加進(jìn) Go 特性中,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Go語言sync.Pool對象池使用場景基本示例

    Go語言sync.Pool對象池使用場景基本示例

    這篇文章主要為大家介紹了Go語言sync.Pool對象池使用場景的基本示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 詳解Go中的高效切片拼接和Go1.22提供的新方法

    詳解Go中的高效切片拼接和Go1.22提供的新方法

    在?Go?語言中,切片拼接是一項(xiàng)常見的操作,但如果處理不當(dāng),可能會導(dǎo)致性能問題或意外的副作用,本文將詳細(xì)介紹幾種高效的切片拼接方法,希望對大家有所幫助
    2024-01-01
  • Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    本文主要介紹了Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • Golang共享變量如何解決問題

    Golang共享變量如何解決問題

    協(xié)程之間的通信只能夠通過通道。但是我們習(xí)慣于共享變量,而且很多時候使用共享變量能讓代碼更簡潔。那么Golang共享變量如何解決問題,感興趣的可以了解一下
    2021-12-12
  • 詳解Go語言中net/http包的使用

    詳解Go語言中net/http包的使用

    Go語言內(nèi)置的?net/http?包十分的優(yōu)秀,提供了HTTP客戶端和服務(wù)端的實(shí)現(xiàn),本文主要就來和大家聊聊net/http包的使用,感興趣的可以了解一下
    2023-07-07
  • Go語言題解LeetCode705設(shè)計(jì)哈希集合

    Go語言題解LeetCode705設(shè)計(jì)哈希集合

    這篇文章主要為大家介紹了Go語言題解LeetCode705設(shè)計(jì)哈希集合,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • golang中snappy的使用場合實(shí)例詳解

    golang中snappy的使用場合實(shí)例詳解

    在java 和go語言 大字符傳達(dá)的時候, 采用snappy 壓縮 解壓縮是最好的方案。下面這篇文章主要給大家介紹了關(guān)于golang中snappy使用場合的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-12-12
  • go開源項(xiàng)目用戶名密碼驗(yàn)證的邏輯鬼才寫法

    go開源項(xiàng)目用戶名密碼驗(yàn)證的邏輯鬼才寫法

    這篇文章主要為大家介紹了go開源項(xiàng)目中發(fā)現(xiàn)的一個邏輯鬼才寫法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07

最新評論

阳江市| 鸡西市| 石首市| 乐安县| 财经| 井陉县| 吉隆县| 全州县| 株洲县| 上虞市| 齐齐哈尔市| 子洲县| 贞丰县| 龙南县| 康平县| 宜州市| 依安县| 楚雄市| 缙云县| 左贡县| 蒙自县| 安义县| 靖州| 浙江省| 外汇| 榆社县| 罗定市| 年辖:市辖区| 休宁县| 安阳县| 将乐县| 永寿县| 彝良县| 轮台县| 陆河县| 祁门县| 元江| 华容县| 广安市| 郯城县| 泊头市|