【Go學習筆記6】使用者自定義型別和方法

zhongzhong05發表於2017-12-11

自定義型別

在go語言中,使用者可以自定義型別。類似於C語言中的結構體,go語言中使用struct來定義自定義的型別。

建立自定義型別

package main

import (
	"fmt"
)

//自定義型別
type person struct{
	id int
	name string
	age int
}

func main(){
	var p person
	fmt.Println("id=",p.id,",name=",p.name,",age=",p.age)
}
//id= 0 ,name=  ,age= 0
複製程式碼

上面的程式碼定義了一個自定義的person型別,因為沒有給p賦值,所以p裡面的所有屬性都是預設值。

package main

import (
	"fmt"
)

//自定義型別
type person struct{
	id int
	name string
	age int
}

func main(){
	p := person{
		id:1,
		name:"zhongzhong",
		age:25,
	}
	fmt.Println("id=",p.id,",name=",p.name,",age=",p.age)
}

//id= 1 ,name= zhongzhong ,age= 25
複製程式碼

上面的程式碼宣告並且初始化了person型別的變數p,注意,初始化的時候,每一行後面以逗號結尾,最後一行也必須要逗號結尾,否則會報錯。

package main

import (
	"fmt"
)

//自定義型別
type person struct{
	id int
	name string
	age int
}

func main(){
	p := person{1,"zhongzhong",25}
	fmt.Println("id=",p.id,",name=",p.name,",age=",p.age)
}


複製程式碼

上面的程式碼使用了另一種方式來初始化p,在{}中直接使用屬性的值來初始化,而不需要指定屬性的名稱。每個屬性的值使用逗號隔開,注意,末尾沒有逗號。 這種寫法,屬性的值必須和屬性的順序一致。

方法

在go語言中,方法也是函式,但是方法的宣告和函式的宣告有些差異,在宣告方法的時候,必須在func關鍵字和函式名稱之間加一個引數,這個引數用來表示這個方法的接收者,看下面的程式碼:

package main

import (
	"fmt"
)

//自定義型別
type person struct{
	id int
	name string
	age int
}

//宣告瞭一個函式
func fn(){
	fmt.Println("這是一個函式")
}

//宣告一個函式,函式有一個string型別的引數
//函式的返回值有兩個,第一個是一個string型別的值
//第二個是一個int型別的值
func fn1(name string) (string,int){
		return "",0
}

//宣告瞭一個方法,這個方法的接受者為person
func (p person) hello(){
	fmt.Println("hello,我是",p.name)
}

func main(){
	//呼叫函式
	fn()

	p := person{1,"zhongzhong",25}
	//呼叫方法
	p.hello()
}

//這是一個函式
//hello,我是 zhongzhong
複製程式碼

從上面的程式碼中可以看出,方法需要指定一個方法的接收者,也就是在將來呼叫的方法的是什麼型別。可以理解為,一個方法宣告的時候,就已經知道了,這個方法屬於哪種型別,而且只能被指定的型別所呼叫。

package main

import (
	"fmt"
)

//自定義型別
type person struct{
	id int
	name string
	age int
}


//宣告瞭一個方法,這個方法的接受者為person
func (p person) changeName(){
	p.name = "new name"
}

//宣告第二個方法,這個方法的接受者為*person
func (p *person) changeName2(){
	p.name = "new name2"
}

func main(){

	p := person{1,"zhongzhong",25}

	p.changeName()
	fmt.Println(p.name)

	p.changeName2()
	fmt.Println(p.name)
}

//zhongzhong
//new name2
複製程式碼

在宣告的程式碼中,第二個方法宣告有點特殊,方法的接受者為person型別的指標,然後我們在main中分別呼叫了changeName和changeName2兩個方法,可以發現changeName並沒有改變name的值 而changName2改變了name的值。這是因為changeName中傳遞的是p的拷貝,而在changeName2中傳遞個是p的記憶體地址,所以對於changeName2這個方法的接受者引數的修改,都會反應到p上面。

問題:changeName2中的接收者型別明明是要給指標,而我們傳遞給它的卻是一個person型別的值,並不是一個指標,那麼為什麼也可以正常呼叫呢?

這是因為在go語言中,會自動對接受者做出調整,上面的程式碼p.changeName2()在go語言處理之後, 會變成(&p).changeName2()來呼叫,這樣就符合了changeName2宣告的接受者引數的型別了,呼叫自然也就成功了。

總結:

在這篇文章中我們講解了如何使用struct關鍵字定義自定義型別, 以及如何通過方法來擴充套件自定義型別。還講解了方法的接受者為值和指標時的區別。

相關文章