go語言學習-結構體

來源:互聯網
上載者:User

標籤:注意   支援   tom   方式   引用   混合   針對   也有   返回   

結構體

go語言中的結構體,是一種複合類型,有一組屬性構成,這些屬性被稱為欄位。結構體也是實值型別,可以使用new來建立。

定義:

type name struct {    field1 type1    field2 type2    ...}

我們可以看到每一個欄位都由一個名字和一個類型構成,不過實際上,如果我們如果不需要使用某個欄位時,可以使用”_”來代替它的名字

並且結構體欄位可以是任意類型,函數,介面,甚至是結構體本身都可以

使用結構體

定義一個Person結構體

type Person struct {    name string    age  int}

使用

// 字面量形式初始化var p1 = Person{    name: "Tom",    age: 18,}var p2 = Person{"Cat", 20}fmt.Println(p1)          //{Tom 18}                                                                                     fmt.Println(p1.name)     // Tomfmt.Println(p2)          // {Cat 20}p1.age = 20      // 設定p的age欄位的值fmt.Println(p1)     // {Tom 20}還可以使用new函數來給一個結構體分配記憶體,並返回指向已指派記憶體的指標var p3 *Person   // 聲明一個Person類型的指標p3 = new(Person)   // 分配記憶體// 上面兩句相當於p3 := new(Person)p3.name = "Cat"p3.age = 10fmt.Println(p3)       // &{Cat 10}fmt.Println(p3.name)  // 

我們可以直接使用結構體指標通過”.”來訪問結構體的欄位,就像直接使用結構體執行個體一樣, go會自動進行轉換

還有一種叫做混合字面量的文法來聲明,如下,這其實只是一種簡寫方式,底層還是調用new方法

var p4 = &Person{"Dog", 10}  // 同樣返回的是Person類型的指標fmt.Println(p4)             // &{Dog 10}fmt.Println(p4.name)        // Dog
匿名欄位

go語言的結構體還支援匿名欄位,也就是說一個只有類型而沒有欄位名(連”_”都沒有)的欄位,被匿名嵌入的也可以是任何類型,此時類型名就是欄位的名字,也就是我們可以直接使用類型名為欄位名來訪問匿名欄位.

另外如果匿名欄位是另一個結構體,這就叫做內嵌結構體,這個特性可以類比類似繼承的行為。

type Person struct {    name string    age  int}type Student struct {    Person    int}// 定義一個Student類型的變數var s = Student{Person{"gdb", 10}, 10}// 可以使用如下的方法訪問內部結構體中的欄位fmt.Println(s.Person.name)// 也可以這樣訪問,go將自動使用Person的name屬性,不過如果在Student中也定義了name欄位,這裡就不能使用了fmt.Println(s.name)// 訪問int類型的匿名欄位,此時類型就是欄位的名字fmt.Println(s.int)

注意:這樣如果兩個欄位有相同的名字時,外部的名字會覆蓋內部的;如果同一層級出現相同名字的欄位,會出錯,需要注意;並且不能同時嵌?某?類型和其指標類型,因為它們名字相同。

標籤

結構體中的欄位除了可以有名稱和類型以外,還可以有標籤。它是一個附屬於欄位的字串,可以是文檔或其他的重要標記。後面說反射時再說。

方法

之前學習的物件導向語言,比如說Java, Python中,有類的概念,每個類都可以有自己的成員變數,成員方法,它們都是定義在類中的

go語言中的結構體就類似與物件導向語言的類,而結構體的欄位就相當於類中的成員變數,結構體也可以有方法,但是不是直接定義在結構體中的,go語言中有一個接收者的概念,我們可以將函數作用在一個接收者,此時這個函數就被稱為方法

接收者是某種類型的變數,不僅僅可以是結構體,幾乎任何類型都可以是結構體,比如: int,bool, string或數組的別名資料型別,甚至可以是函數類型,不過不能是介面類型

定義方法的樣本:

type Person struct {    name string    age int}// 使用Person類型的執行個體做接收者,這就是一個Person類型方法,方法名前面括弧中的就是接收者func (this Person) getName() string {    return this.name}// Peron類型的指標對象也可以作為接收者func (this *Person) setName(name string) {    this.name = name}tom := Person{"Tom", 20}fmt.Println(tom)  // {Tom 20}fmt.Println(tom.getName())  // Tomtom.changeName("Bob")fmt.Println(tom)  // {Bob 20}

這裡有一點需要注意:類型和綁定它的方法必須在同一個包中(不一定要在同一個檔案中)

這裡使用類型直接作為接收著 和 類型的指標作為接收者的區別,就相當於普通函數中,實值型別的參數和參考型別參數的區別;即在方法中對類型的執行個體的操作,不會影響外部的執行個體的值,而使用類型指標的執行個體作為引用參數,在方法內部修改會影響外部的執行個體

匿名欄位

我們也可以使用結構體內部的匿名欄位,作為方法的接收者,此時這個結構體,仍然可以調用這個方法,此時編譯器會負責尋找

type Person struct {    name string    age int}type Student struct {    Person    score int}func (p *Person) show() {    fmt.Println("My name is " + p.name + ", I‘m " + strconv.Itoa(p.age) + " years old")}tom := Person{"Tom", 20}// 調用匿名欄位作為接收器的方法tom.show()   // My name is Tom, I‘m 20 years old

在此基礎上,我們還可以在結構體上,實現與匿名欄位同名的方法,就像物件導向中的重寫類似,編譯器會先尋找結構體執行個體作為接收器的方法。

方法集

根據定義結構體以及方法的不同,方法集也有所不同,瞭解他們,對理解介面有協助

type T struct {    name string    age int}type G struct {    T    action string}type S struct {    *T    sel string}
  • 類型 T 的方法集包含所有接收者為 T 的方法
  • 類型T的方法集包含所有接收者為 T的方法(因為go會自動解引用)和所有接收者為 T 的方法
  • 類型G包含匿名欄位 T, 則G的方法集,僅僅包含T類型的方法集
  • 類型S包含匿名欄位 *T,則S的方法集,包含T和*T類型的方法集

go語言學習-結構體

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.