Golang 結構體與方法|Go主題月

結構體

結構體是 go 語言中一個比較重要的概念,在 c 語言中也有相似的東西。因爲他們沒有類的概念,結構體能夠簡單理解成類,是一個不一樣類型的數據構成的一個集合。集合中不一樣類型的數據被稱爲成員,每一個成員都要本身不一樣的類型,能夠理解爲 js 中對象的每一個屬性。markdown

聲明結構體

結構體經過 typestruct 關鍵字進行聲明,type 後接結構體的名字,struct 後接結構體每一個成員的定義。函數

type Person struct {
  name string
  age int
  gender string
  address string
}
複製代碼

上面代碼有點相似於其餘語言中接口的定義,實際上,go 也支持定義接口,咱們只須要將 struct 關鍵字替換成 interface 就表示定義接口。ui

初始化結構體

初始化結構體有兩種方式,一種是經過字面量的方式,用結構體名稱加上結構體各個成員值的方式進行初始化。用上面的 Person 結構體舉例:spa

var p = Person{"Shenfq", 25, "男", "湖南長沙"}
fmt.Println("Person:", p)
複製代碼

這種方式須要每一個值按照結構體成員定義時的順序進行初始化,固然,也能夠經過鍵值對的方式,打亂其順序。這種方式能夠對部分紅員進行省略,省略的部分會根據其類型,取該類型的空值。指針

var p = Person{
  name: "Shenfq",
  address: "湖南長沙",
}

fmt.Println("Person:", p)
fmt.Println("Person.age:", p.age)
複製代碼

若是要訪問結構體成員,能夠經過 . 操做符,這與其餘語言取對象屬性的方式一致。這裏咱們使用 p.age 的方式獲取告終構體 p 的成員 age 的值。code

除了字面量的方式初始化,結構體還能夠經過 new 關鍵字進行初始化。orm

var p = new(Person)
複製代碼

經過該方式初始化的結構體有兩個特色:對象

  • new 關鍵字返回的爲結構體指針;
  • new 關鍵字返回的結果每一個成員都是空值;

因此,咱們經過 new 初始化結構體的時候,取值的時候須要加 * 號。接口

var p = new(Person)
p.name = "Shenfq"
p.age = 18
p.gender = "男"
p.address = "湖南長沙"

fmt.Println("Person:", p)
複製代碼

若是直接在控制檯打印變量 p,會發現前面有個 &,表示這是一個指針。string

匿名結構體

結構體和函數同樣也能夠定義一個沒有名字的結構體,就是在定義結構體的同時進行初始化,而且省略 type 關鍵字和結構體名稱。

var p = struct {
  name string
  age int
  gender string
  address string
} { "Shenfq", 25, "男", "湖南長沙"}
複製代碼

方法

結構體只能定義一個個成員,並且成員都是基礎類型,想要實現相似 OOP 中類的概念,還須要爲結構體提供方法。實際上,咱們能夠爲結構體指定方法,只須要在定義函數的函數名前面加上結構體名,就能定義該函數爲結構體的方法。

咱們爲以前的 Person 結構體定義一個 sayHello 的方法。

func (p Person) sayHello(name string) {
	fmt.Printf("Hi %s, I'm %s, How are you?\n", name, p.name)
}
p.sayHello("Jack")
複製代碼

調用結構體方法的方式,和取結構體成員的值同樣,也須要經過 . 操做符。

在 goland 的 Structure 中,能看到 Person 結構體是包含 sayHello 方法的,說明方法的定義即便不在結構體內,這個方法也是屬於該結構體的。

方法中的指針

有時候,咱們調用方法的同時,須要修改結構體中一些成員的值,會發現原結構體的值並無改變。

func (p Person) growth() {
	p.age++
}

var p = Person{ age: 25 }
p.growth()
複製代碼

上面的代碼中,咱們定義的 growth 方法,會修改傳入結構體中的 age 值。可是實際結果和咱們預期的不同。

var p = Person{ age: 25 }

p.growth()
fmt.Println("age:", p.age)
複製代碼

這是因爲,傳入方法中的結構體,是原結構體複製後的值,須要修改原結構體,就須要給方法傳入其指針。只須要在方法定義結構體參數時,加上 * 號,表示變量 p 爲結構體指針。

func (p *Person) growth() {
	p.age++
}
複製代碼

相關文章
相關標籤/搜索