1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Go 專欄|說(shuō)說(shuō)方法

        共 3422字,需瀏覽 7分鐘

         ·

        2021-08-31 21:14

        最近又搬家了,已經(jīng)記不清這是第幾次搬家了。搬到了公司附近,走路十分鐘,以后加班可方便了。

        這一篇來(lái)說(shuō)一說(shuō)方法,方法可以看作是某種特定類型的函數(shù),是 Go 面向?qū)ο缶幊痰牡谝徊?。用好方法,具備面向?qū)ο缶幊趟枷胧顷P(guān)鍵。

        聲明

        方法的聲明和函數(shù)類似,他們的區(qū)別是:方法在定義的時(shí)候,會(huì)在 func 和方法名之間增加一個(gè)參數(shù),這個(gè)參數(shù)就是接收者,這樣我們定義的這個(gè)方法就和接收者綁定在了一起,稱之為這個(gè)接收者的方法。

        type Person struct {
            name string
        }

        func (p Person) String() string {
            return "person name is " + p.name
        }

        func 和方法名之間增加的參數(shù) (p Person)  就是接收者。現(xiàn)在我們說(shuō),類型 Person 有了一個(gè) String 方法。

        調(diào)用方法非常簡(jiǎn)單,使用類型的變量和 . 操作符進(jìn)行調(diào)用即可。

        p := Person{name: "zhangsan"}

        // 調(diào)用方法
        fmt.Println(p.String()) // person name is zhangsan

        值語(yǔ)義和引用語(yǔ)義

        Go 語(yǔ)言里有兩種類型的接收者:值接收者和指針接收者。

        使用值類型接收者定義的方法,在調(diào)用的時(shí)候,使用的其實(shí)是值接收者的一個(gè)副本,所以對(duì)該值的任何操作,不會(huì)影響原來(lái)的類型變量。

        func main() {
            p := Person{name: "zhangsan"}

            // 調(diào)用方法
            fmt.Println(p.String()) // person name is zhangsan

            // 值接收者
            p.Modify()
            fmt.Println(p.String()) // person name is zhangsan
        }

        // 值接收者
        func (p Person) Modify() {
            p.name = "lisi"
        }

        接下來(lái)再看一下使用指針接收者的效果:

        func main() {
            p := Person{name: "zhangsan"}

            // 調(diào)用方法
            fmt.Println(p.String()) // person name is zhangsan

            // 指針接收者
            p.ModifyP()
            fmt.Println(p.String()) // person name is lisi
        }

        // 指針接收者
        func (p *Person) ModifyP() {
            p.name = "lisi"
        }

        可以看到,改變了原始值,其實(shí)這一點(diǎn)和函數(shù)傳參是一樣的。

        有沒(méi)有發(fā)現(xiàn),我們?cè)谡{(diào)用指針接收者方法的時(shí)候,使用的也是一個(gè)值的變量,并不是一個(gè)指針,正常來(lái)說(shuō)應(yīng)該這么寫:

        (&p).ModifyP()
        fmt.Println(p.String())

        同樣的,如果是一個(gè)值接收者的方法,使用指針也是可以調(diào)用的:

        (&p).Modify()
        fmt.Println(p.String())

        原因是編譯器幫我們自動(dòng)轉(zhuǎn)義了,這一點(diǎn)大大的方便了我們開發(fā)者。

        方法變量和表達(dá)式

        上文中已經(jīng)介紹了一種調(diào)用方法,直接使用 . 操作符,比如:p.String()

        接下來(lái)再介紹兩種調(diào)用方法:

        方法變量

        p.Add 可以賦值給一個(gè)方法變量,它相當(dāng)于一個(gè)函數(shù),把方法綁定到一個(gè)接收者上。然后函數(shù)只需要提供實(shí)參而不需要提供接收者即可調(diào)用。

        type Point struct {
            x, y int
        }

        func main() {
            // 方法變量
            p1 := Point{12}
            q1 := Point{34}
            f := p1.Add
            fmt.Println(f(q1)) // {4 6}
        }

        func (p Point) Add(q Point) Point {
            return Point{p.x + q.x, p.y + q.y}
        }

        方法表達(dá)式

        方法表達(dá)式寫成 T.f 或者 (*T).f,其中 T 是類型,是一種函數(shù)變量。

        因?yàn)檎{(diào)用方法必須要提供接收者,這種方法相當(dāng)于把接收者替換成了函數(shù)的第一個(gè)形參,因此它可以像函數(shù)一樣調(diào)用。

        // 方法表達(dá)式
        f1 := Point.Add
        fmt.Println(f1(p1, q1)) // {4 6}

        總結(jié)

        本文主要學(xué)習(xí)了 Go 的方法,方法的聲明和函數(shù)類似,他們的區(qū)別是:方法在定義的時(shí)候,會(huì)在 func 和方法名之間增加一個(gè)參數(shù),這個(gè)參數(shù)就是接收者。

        接收者有兩種類型:值接收者和指針接收者。不管是使用值接收者,還是指針接收者,一定要搞清楚類型的本質(zhì):對(duì)類型進(jìn)行操作的時(shí)候,是要改變當(dāng)前值,還是要?jiǎng)?chuàng)建一個(gè)新值進(jìn)行返回?這些就可以決定我們是采用值傳遞,還是指針傳遞。

        最后就是方法的調(diào)用,可以直接使用 . 操作符調(diào)用,還可以使用方法變量和方法表達(dá)式。

        只有基于面向?qū)ο缶幊趟枷耄拍苁褂煤梅椒?。在后面要學(xué)習(xí)的接口中,方法還有更多的應(yīng)用。


        文章中的腦圖和源碼都上傳到了 GitHub,有需要的同學(xué)可自行下載。

        地址: https://github.com/yongxinz/gopher/tree/main/sc

        關(guān)注公眾號(hào) AlwaysBeta,回復(fù)「goebook」領(lǐng)取 Go 編程經(jīng)典書籍。

        Go 專欄文章列表:

        瀏覽 35
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            免费在线观看成人网站 | 91精品秘 无码一区二区山手 | 停停久久 | 五十路一区二区 | 日逼高清无码 | 日逼视频播放 | 欧美丰满爆乳成人无码视频东京热 | 国产成人视频免费观看 | 麻豆视频在线播放 | 日本豆花视频 |