golang類和結構體

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

golang結構體和類

golang中並沒有明確的物件導向的說法,實在要扯上的話,可以將struct比作其它語言中的class。

類聲明

type Poem struct {    Title  string    Author string    intro  string}

這樣就聲明了一個類,其中沒有public、protected、private的的聲明。golang用另外一種做法來實現屬性的存取權限:屬性的開頭字母是大寫的則在其它包中可以被訪問,否則只能在本包中訪問。類的聲明和方法亦是如此。
注意:

p1 := &Poem{        "zhangsan",        25,        []string{"lisi", "wangwu"},    }

使用中如果包含數組,結構體的執行個體化需要加上類型如上如果intro的類型是[]string。

類方法聲明

func (poem *Poem) publish() {    fmt.Println("poem publish")}

或者

func (poem Poem) publish() {    fmt.Println("poem publish")}

和其它語言不一樣,golang聲明方法和普通方法一致,只是在func後增加了poem Poem這樣的聲明。加和沒有加*的區別在於一個是傳遞指標對象,一個是傳遞值對象。

傳遞指標和對象的區別

type T struct {    Name string}func (t T) M1() {    t.Name = "name1"}func (t *T) M2() {    t.Name = "name2"}

M1() 的接收者是實值型別 T, M2() 的接收者是實值型別 *T , 兩個方法內都是改變Name值。

下面聲明一個 T 類型的變數,並調用 M1() 和 M2() 。

    t1 := T{"t1"}    fmt.Println("M1調用前:", t1.Name)    t1.M1()    fmt.Println("M1調用後:", t1.Name)    fmt.Println("M2調用前:", t1.Name)    t1.M2()    fmt.Println("M2調用後:", t1.Name)

輸出結果為:

M1調用前: t1
M1調用後: t1
M2調用前: t1
M2調用後: name2

下面猜測一下go會怎麼處理。

先來約定一下:接收者可以看作是函數的第一個參數,即這樣的: func M1(t T), func M2(t *T)。 go不是物件導向的語言,所以用那種看起來像物件導向的文法來理解可能有偏差。

當調用 t1.M1() 時相當於 M1(t1) ,實參和行參都是類型 T,可以接受。此時在M1()中的t只是t1的值拷貝,所以M1()的修改影響不到t1。

當調用 t1.M2() => M2(t1),這是將 T 類型傳給了 *T 類型,go可能會取 t1 的地址傳進去: M2(&t1)。所以 M2() 的修改可以影響 t1 。

匿名結構體

p := struct {    Name string    Gender string    Age uint8}{"Robert", "Male", 33}

匿名結構體最大的用處是在內部臨時建立一個結構以封裝資料,而不必正式為其聲明相關規則。

執行個體化對象

執行個體化對象有好幾種方式

poem := &Poem{}poem.Author = "Heine"poem2 := &Poem{Author: "Heine"}poem3 := new(Poem)poem3.Author = "Heine"poem4 := Poem{}poem4.Author = "Heine"poem5 := Poem{Author: "Heine"}

執行個體化的時候可以初始化屬性值,如果沒有指明則預設為系統預設值

加&符號和new的是指標對象,沒有的則是值對象,這點和php、java不一致,在傳遞對象的時候要根據實際情況來決定是要傳遞指標還是值。

tips:當對象比較小的時候傳遞指標並不划算。

建構函式(自己創造)

func NewPoem(param string, p ...interface{}) *Poem

樣本:

func NewPoem(author string) (poem *Poem) {    poem = &Poem{}    poem.Author = author    return}poem6 := NewPoem("Heine")

繼承

確切的說golang中叫做組合(composition)

type Poem struct {    Title  string    Author string    intro  string}type ProsePoem struct {    Poem    Author string}

ProsePoem屬性中聲明了Poem,表示組合了Poem的屬性和方法。可以像如下方式調用:

prosePoem := &ProsePoem{}prosePoem.author = "Heine"

如果其中屬性有衝突,則以外圍的為主,也就是說會被覆蓋。

type ProsePoem struct {    Poem    Author string}

當訪問Author的時候預設為ProsePoem的Author,如果需要訪問Poem的Author屬性可以使用
prosePoem.Poem.Author來訪問。

prosePoem := &ProsePoem{}prosePoem.Author = "Shelley"prosePoem.Poem.Author = "Heine"fmt.Println(prosePoem)

從輸出中可以很直觀看到這一點。

&{{ Heine } Shelley}

方法的繼承和屬性一致,這裡不再羅列。通過組合的話可以很好的實現多繼承。

方法重載

方法重載就是一個類中可以有相同的函數名稱,但是它們的參數是不一致的,在java、C++中這種做法普遍存在。golang中如果嘗試這麼做會報重新聲明(redeclared)錯誤,但是golang的函數可以聲明不定參數,這個非常強大。

func (poem *Poem) recite(v ...interface{}) {

fmt.Println(v)

}

其中v …interface{}表示參數不定的意思,其中v是slice類型,fmt.Println方法也是這樣定義的。如果要根據不同的參數實現不同的功能,要在方法內檢測傳遞的參數。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.