【高級數據類型2】- 8. 結構體和方法

Go語言-結構體和方法

    Go語言的結構體類型(Struct)比函數類型更加靈活。它能夠封裝屬性和操做。前者便是結構體類型中的字段,然後者則是結構體類型所擁有的方法。
  
    結構體類型的字面量由關鍵字type、類型名稱、關鍵字struct,以及由花括號包裹的若干字段聲明組成。其中,每一個字段聲明獨佔一行並由字段名稱(可選)和字段類型組成。示例以下:編程

type Person struct {
    Name   string
    Gender string
    Age    uint8
}

    結構體類型Person中有三個字段,分別是NameGenderAge。咱們能夠用字面量建立出一個該類型的值,像這樣:併發

Person{Name: "Robert", Gender: "Male", Age: 33}

    能夠看到,結構體值的字面量(或簡稱結構體字面量)由其類型的名稱和由花括號包裹的若干鍵值對組成。注意,這裏的鍵值對與字典字面量中的鍵值對的寫法類似,但不相同。這裏的鍵是其類型中的某個字段的名稱(注意,它不是字符串字面量),而對應的值則是欲賦給該字段的那個值。另外,若是這裏的鍵值對的順序與其類型中的字段聲明徹底相同的話,咱們還能夠統一省略掉全部字段的名稱,就像這樣:函數

Person{"Robert", "Male", 33}

    固然,咱們在編寫某個結構體類型的值字面量時能夠只對它的部分字段賦值,甚至不對它的任何字段賦值。這時,未被顯式賦值的字段的值則爲其類型的零值。注意,在上述兩種狀況下,字段的名稱是不能被省略的。
    
    與表明函數值的字面量相似,咱們在編寫一個結構體值的字面量時不須要先擬好其類型。這樣的結構體字面量被稱爲匿名結構體。與匿名函數相似,咱們在編寫匿名結構體的時候須要先寫明其類型特徵(包含若干字段聲明),再寫出它的值初始化部分。下面,咱們依照結構體類型Person建立一個匿名結構體:ui

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

    匿名結構體最大的用處就是在內部臨時建立一個結構以封裝數據,而沒必要正式爲其聲明相關規則。而在涉及到對外的場景中,我強烈建議使用正式的結構體類型。
  
    我在本節開始處提到過,結構體類型能夠擁有若干方法(注意,匿名結構體是不可能擁有方法的)。所謂方法,其實就是一種特殊的函數。它能夠依附於某個自定義類型。方法的特殊在於它的聲明包含了一個接收者聲明。這裏的接收者指代它所依附的那個類型。咱們仍以結構體類型Person爲例。下面是依附於它的一個名爲Grow的方法的聲明:spa

func (person *Person) Grow() {
    person.Age++
}

    如上所示,在關鍵字func和名稱Grow之間的那個圓括號及其包含的內容就是接收者聲明。其中的內容由兩部分組成。第一部分是表明它依附的那個類型的值的標識符。第二部分是它依附的那個類型的名稱。後者代表了依附關係,而前者則使得在該方法中的代碼可使用到該類型的值(也稱爲當前值)。表明當前值的那個標識符可被稱爲接收者標識符,或簡稱爲接收者。請看下面的示例:指針

p := Person{"Robert", "Male", 33}
p.Grow()

    咱們能夠直接在Person類型的變量p之上應用調用表達式來調用它的方法Grow。注意,此時方法Grow的接收者標識符person指代的正是變量p的值。這也是「當前值」這個詞的由來。在Grow方法中,咱們經過使用選擇表達式選擇了當前值的字段Age,並使其自增。所以,在語句p.Grow()被執行以後,p所表明的那我的就又年長了一歲(pAge字段的值已變爲34)。
  
    須要注意的是,在Grow方法的接收者聲明中的那個類型是*Person,而不是Person。實際上,前者是後者的指針類型。這也使得person指代的是p的指針,而不是它自己。至於爲何這麼作,咱們在講指針的時候在予以揭曉。
  
    說到這裏,熟悉面向對象編程的同窗可能已經意識到,包含若干字段和方法的結構體類型就至關於一個把屬性和操做封裝在一塊兒的對象。不過要注意,與對象不一樣的是,結構體類型(以及任何類型)之間都不可能存在繼承關係。實際上,在Go語言中並無繼承的概念。不過,咱們能夠經過在結構體類型的聲明中添加匿名字段(或稱嵌入類型)來模仿繼承。具體細節能夠參考《Go併發編程實戰》中的說明,或者關注個人後續課程。
  
    最後,結構體類型屬於值類型。它的零值並非nil,而是其中字段的值均爲相應類型的零值的值。舉個例子,結構體類型Person的零值若用字面量來表示的話則爲Person{}code

相關文章
相關標籤/搜索