自定義型別
在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關鍵字定義自定義型別, 以及如何通過方法來擴充套件自定義型別。還講解了方法的接受者為值和指標時的區別。