如果對(duì)與結(jié)構(gòu)體還有什么疑問的可以看一下Golang學(xué)習(xí)筆記之結(jié)構(gòu)體
?法總是綁定對(duì)象實(shí)例着帽,并隱式將實(shí)例作為第?實(shí)參 (receiver)。
? 只能為當(dāng)前包內(nèi)命名類型定義?法竿秆。
? 參數(shù) receiver 可任意命名启摄。如?法中未曾使?,可省略參數(shù)名幽钢。
? 參數(shù) receiver 類型可以是 T 或 *T「凳牵基類型 T 不能是接?或指針匪燕。
? 不?持?法重載, receiver 只是參數(shù)簽名的組成部分喧笔。
? 可?實(shí)例 value 或 pointer 調(diào)?全部?法帽驯,編譯器?動(dòng)轉(zhuǎn)換。
? Go 不允許同名函數(shù)书闸,但是同名方法可以定義在不同的類型上
? method和receiver必須在同一個(gè)包里定義
? 作為函數(shù)參數(shù)尼变,值類型就是值類型,指針類型就是指針類型
? 方法有一個(gè)值類型和指針類型的接受者時(shí),都可以直接調(diào)用嫌术,內(nèi)部會(huì)
自動(dòng)進(jìn)行語(yǔ)法的轉(zhuǎn)換哀澈。
一個(gè)方法只是一個(gè)函數(shù),它有一個(gè)特殊的接收者(receiver)類型度气,該接收者放在 func 關(guān)鍵字和函數(shù)名之間割按。接收者可以是結(jié)構(gòu)體類型或非結(jié)構(gòu)體類型×准可以在方法內(nèi)部訪問接收者适荣。
一般語(yǔ)法為:
func (t receiver_type) methodName(parameter list) {}
一、參數(shù) receiver 類型可以是 T 或 *T院领。以指針為接收者也是可以的弛矛。
兩者的區(qū)別在于, 以*T為接收者時(shí)比然,方法內(nèi)部對(duì)其的修改對(duì)于外部有效丈氓,而以 T作為接受者時(shí),對(duì)于外部無(wú)效谈秫。
func (e Employee) changeName(newName string) {
e.name = newName
}
func (e *Employee) changeAge(newAge int) {
e.age = newAge
}
emp1 := Employee{
name: "張三",
salary: 6000,
currency: "$",
age: 18,
Address: Address{"山東", "濟(jì)南"},
}
emp1.displaySalary()
fmt.Println("Before call changeName ", emp1.name)
//修改名字扒寄,未發(fā)生變化因?yàn)槭侵祩鬟f
emp1.changeName("zhangsan")
fmt.Println("After call changeName ", emp1.name) //After call changeName 張三
fmt.Println("Before change age", emp1.age)
//利用指針來修改年齡
emp1.changeAge(50)
fmt.Println("After change age", emp1.age) //After change age 50
二、Go 不允許同名函數(shù)拟烫,但是同名方法可以定義在不同的類型上
//Rectangle 代碼規(guī)范
type Rectangle struct {
width float32
height float32
}
//Circle 代碼規(guī)范
type Circle struct {
radius float32
}
func (e Employee) changeName(newName string) {
e.name = newName
}
func (e *Employee) changeAge(newAge int) {
e.age = newAge
}
func main() {
//計(jì)算面積
re := Rectangle{20, 30}
c := Circle{40}
//兩個(gè)類型調(diào)用同名方法
fmt.Println(re.getArea())
fmt.Println(c.getArea())
}
三该编、提階,方法也支持提階
emp1 := Employee{
name: "張三",
salary: 6000,
currency: "$",
age: 18,
Address: Address{"山東", "濟(jì)南"},
}
//提階
emp1.fullAddress() //山東 濟(jì)南硕淑,提階相當(dāng)于直接訪問Address里的
emp1.Address.fullAddress() //山東 濟(jì)南
四课竣、非結(jié)構(gòu)類型的方法
非結(jié)構(gòu)體類型也可以定義方法,不過這里需要注意一點(diǎn)置媳。為了定義某個(gè)類型的方法于樟,接收者類型的定義與方法的定義必須在同一個(gè)包中。
因?yàn)楸仨氃谝粋€(gè)包中而int則在main包中我們沒法去定義這個(gè)里為了簡(jiǎn)單直觀拇囊,給int聲明了別名
//非結(jié)構(gòu)體方法擴(kuò)展
type myInt int
func (a myInt) add(b myInt) myInt {
return a + b
}
func main() {
//調(diào)用擴(kuò)展的方法
num1 := myInt(5)
num2 := myInt(10)
sum := num1.add(num2)
fmt.Println("Sum is", sum)
}
下面附上完整實(shí)例程序
package main
import (
"fmt"
"math"
)
//Employee 需要添加注釋或者改成非導(dǎo)出變量(首字母小寫)
type Employee struct {
name string
currency string
salary int
age int
Address
}
//Address 代碼規(guī)范
type Address struct {
city string
state string
}
//Rectangle 代碼規(guī)范
type Rectangle struct {
width float32
height float32
}
//Circle 代碼規(guī)范
type Circle struct {
radius float32
}
//Employee 的方法
func (e Employee) displaySalary() {
fmt.Println(e)
}
func (e Employee) changeName(newName string) {
e.name = newName
}
func (e *Employee) changeAge(newAge int) {
e.age = newAge
}
//Address 的方法
func (add Address) fullAddress() {
fmt.Println(add.city, add.state)
}
//Rectangle 的方法計(jì)算面積
func (r Rectangle) getArea() float32 {
return r.width * r.height
}
//Circle 的方法
func (c Circle) getArea() float32 {
return math.Pi * c.radius * c.radius
}
//非結(jié)構(gòu)體方法擴(kuò)展
type myInt int
func (a myInt) add(b myInt) myInt {
return a + b
}
func main() {
//調(diào)用方法
emp1 := Employee{
name: "張三",
salary: 6000,
currency: "$",
age: 18,
Address: Address{"山東", "濟(jì)南"},
}
emp1.displaySalary()
fmt.Println("Before call changeName ", emp1.name)
//修改名字迂曲,未發(fā)生變化因?yàn)槭侵祩鬟f
emp1.changeName("zhangsan")
fmt.Println("After call changeName ", emp1.name) //After call changeName 張三
fmt.Println("Before change age", emp1.age)
//利用指針來修改年齡
emp1.changeAge(50)
fmt.Println("After change age", emp1.age) //After change age 50
//提階
emp1.fullAddress() //山東 濟(jì)南,提階相當(dāng)于直接訪問Address里的
emp1.Address.fullAddress() //山東 濟(jì)南
//計(jì)算面積
re := Rectangle{20, 30}
c := Circle{40}
//兩個(gè)類型調(diào)用同名方法
fmt.Println(re.getArea())
fmt.Println(c.getArea())
//調(diào)用擴(kuò)展的方法
num1 := myInt(5)
num2 := myInt(10)
sum := num1.add(num2)
fmt.Println("Sum is", sum)
}